mirror of
				https://github.com/boostorg/utility.git
				synced 2025-10-27 22:41:39 +01:00 
			
		
		
		
	Compare commits
	
		
			382 Commits
		
	
	
		
			boost-1.21
			...
			boost-1.37
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | e7890256ae | ||
|  | 9168cb9c61 | ||
|  | e1991374ae | ||
|  | d0ee9a7c28 | ||
|  | 10e83b490b | ||
|  | 4b24dba257 | ||
|  | 7a036f6f3a | ||
|  | e632b0fb1f | ||
|  | 17bee9d43f | ||
|  | 492a8ad213 | ||
|  | 8827b8ed8b | ||
|  | 8849fbc52d | ||
|  | 50bc75a802 | ||
|  | 9b52e49fda | ||
|  | ab479794f3 | ||
|  | 97b8966337 | ||
|  | 88099a882f | ||
|  | d5554eb6d7 | ||
|  | 13bdfb8bbd | ||
|  | 74462349c2 | ||
|  | 6aa648d315 | ||
|  | 9ff18c2c96 | ||
|  | d5ea07c737 | ||
|  | aa0096bf42 | ||
|  | 005c2f3cc8 | ||
|  | 09f7aab52d | ||
|  | 30a40f9f76 | ||
|  | d9f8bae673 | ||
|  | 3c7b409460 | ||
|  | ee3551e8dc | ||
|  | 95da2e90de | ||
|  | 6dd93ab916 | ||
|  | 505d419a1b | ||
|  | d968b5f5b9 | ||
|  | d809d4e832 | ||
|  | 271ea9e901 | ||
|  | 7cd572a326 | ||
|  | 90c56ba2ce | ||
|  | a5439500f5 | ||
|  | c0f0a4f51d | ||
|  | 7594e00460 | ||
|  | f66e844ff1 | ||
|  | 62e8cc2b36 | ||
|  | 30236f8915 | ||
|  | 155e787ea3 | ||
|  | 1d60d49136 | ||
|  | 2dffdac9fe | ||
|  | ddf00eb29d | ||
|  | 0a6acd8ce8 | ||
|  | 745322e797 | ||
|  | 9f10fc03ce | ||
|  | 84fbb3c896 | ||
|  | 865c707756 | ||
|  | 871f3a6779 | ||
|  | aaca5ca871 | ||
|  | 5a4e19989f | ||
|  | 6ea398c446 | ||
|  | 1bd83d43e8 | ||
|  | 5ca5b4102b | ||
|  | aca7699046 | ||
|  | e702a944ca | ||
|  | a157c345ee | ||
|  | dcb2dd4736 | ||
|  | ae19cd6236 | ||
|  | 3ab4d38931 | ||
|  | 18c7fb72b5 | ||
|  | 6bb092a9b1 | ||
|  | f721b8b28c | ||
|  | e5ba34472d | ||
|  | 082ae17eaf | ||
|  | dd86e09ab4 | ||
|  | baff23116e | ||
|  | e549baf93a | ||
|  | 30d46adcb7 | ||
|  | e854726be0 | ||
|  | d198bd9d96 | ||
|  | 5eb23cecd0 | ||
|  | eff2c75bba | ||
|  | 325bd73df7 | ||
|  | 0fcc554abd | ||
|  | b685784155 | ||
|  | ac90fdc611 | ||
|  | 51077e49f5 | ||
|  | 0c3199f72d | ||
|  | 62675a3bcd | ||
|  | c26dbaa620 | ||
|  | 8201624959 | ||
|  | f2116413d6 | ||
|  | b0baebeb0a | ||
|  | fb943b77d5 | ||
|  | b4b39510fc | ||
|  | 6f0f05ba12 | ||
|  | f0b64b6229 | ||
|  | 4229488989 | ||
|  | acd2e6ef2b | ||
|  | c26aaed71f | ||
|  | 326d7ad4d7 | ||
|  | c76a2f4aab | ||
|  | d8b0ff2d7e | ||
|  | 996ce2d307 | ||
|  | 167fa4154f | ||
|  | 0c7e7c3c39 | ||
|  | 9d8f8f41dc | ||
|  | 39c4445b39 | ||
|  | 7819b022ad | ||
|  | 65d27e7f86 | ||
|  | 212a70bf77 | ||
|  | 6b5dc18a46 | ||
|  | 0917f83b9c | ||
|  | 7322bd3903 | ||
|  | e998010184 | ||
|  | 918a1c93e4 | ||
|  | 14c87853c2 | ||
|  | 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 | 
							
								
								
									
										199
									
								
								Assignable.html
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								Assignable.html
									
									
									
									
									
								
							| @@ -1,116 +1,109 @@ | ||||
| <HTML> | ||||
| <!-- | ||||
|   -- Copyright (c) Jeremy Siek 2000 | ||||
|   -- | ||||
|   -- Permission to use, copy, modify, distribute and sell this software | ||||
|   -- and its documentation for any purpose is hereby granted without fee, | ||||
|   -- provided that the above copyright notice appears in all copies and | ||||
|   -- that both that copyright notice and this permission notice appear | ||||
|   -- in supporting documentation.  Silicon Graphics makes no | ||||
|   -- representations about the suitability of this software for any | ||||
|   -- purpose.  It is provided "as is" without express or implied warranty. | ||||
|   --> | ||||
| <Head> | ||||
| <Title>Assignable</Title> | ||||
| </HEAD> | ||||
| <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"  | ||||
|         ALINK="#ff0000">  | ||||
| <IMG SRC="../../c++boost.gif"  | ||||
|      ALT="C++ Boost" width="277" height="86">  | ||||
| <!--end header--> | ||||
| <BR Clear> | ||||
| <H1>Assignable</H1> | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <h3>Description</h3> | ||||
| A type is Assignable if it is possible to assign one object of the type | ||||
| to another object of that type. | ||||
| <html> | ||||
| <head> | ||||
|   <meta http-equiv="Content-Language" content="en-us"> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> | ||||
|  | ||||
|   <title>Assignable</title> | ||||
| </head> | ||||
|  | ||||
| <h3>Notation</h3> | ||||
| <Table> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| <tt>T</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| is type that is a model of Assignable | ||||
| </TD> | ||||
| </TR> | ||||
| <body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink= | ||||
| "#FF0000"> | ||||
|   <img src="../../boost.png" alt="C++ Boost" width="277" height= | ||||
|   "86"><br clear="none"> | ||||
|  | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| <tt>t</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| is an object of type <tt>T</tt> | ||||
| </TD> | ||||
| </tr> | ||||
|   <h1>Assignable</h1> | ||||
|  | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| <tt>u</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| is an object of type <tt>T</tt> or possibly <tt>const T</tt> | ||||
| </TD> | ||||
| </tr> | ||||
|   <h3>Description</h3> | ||||
|  | ||||
| </table> | ||||
| <h3>Definitions</h3> | ||||
| <h3>Valid expressions</h3> | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH> | ||||
| Name | ||||
| </TH> | ||||
| <TH> | ||||
| Expression | ||||
| </TH> | ||||
| <TH> | ||||
| Return type | ||||
| </TH> | ||||
| <TH> | ||||
| Semantics | ||||
| </TH> | ||||
| </TR> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Assignment | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>t = u</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>T&</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>t</tt> is equivalent to <tt>u</tt> | ||||
| </TD> | ||||
| </TR> | ||||
|   <p>A type is Assignable if it is possible to assign one object of the type | ||||
|   to another object of that type.</p> | ||||
|  | ||||
| </table> | ||||
|   <h3>Notation</h3> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr> | ||||
|       <td valign="top"><tt>T</tt></td> | ||||
|  | ||||
| </table> | ||||
| <h3>Models</h3> | ||||
|       <td valign="top">is type that is a model of Assignable</td> | ||||
|     </tr> | ||||
|  | ||||
| <UL> | ||||
| <LI><tt>int</tt> | ||||
| <LI><tt>std::pair</tt> | ||||
| </UL> | ||||
|     <tr> | ||||
|       <td valign="top"><tt>t</tt></td> | ||||
|  | ||||
| <h3>See also</h3> | ||||
| <a href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">DefaultConstructible</A> | ||||
| and  | ||||
| <A href="./CopyConstructible.html">CopyConstructible</A> | ||||
|       <td valign="top">is an object of type <tt>T</tt></td> | ||||
|     </tr> | ||||
|  | ||||
| <br> | ||||
| <HR> | ||||
| <TABLE> | ||||
| <TR valign=top> | ||||
| <TD nowrap>Copyright © 2000</TD><TD> | ||||
| <A HREF=http://www.lsc.nd.edu/~jsiek>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>) | ||||
| </TD></TR></TABLE> | ||||
|     <tr> | ||||
|       <td valign="top"><tt>u</tt></td> | ||||
|  | ||||
| </BODY> | ||||
| </HTML>  | ||||
|       <td valign="top">is an object of type <tt>T</tt> or possibly <tt>const | ||||
|       T</tt></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Definitions</h3> | ||||
|  | ||||
|   <h3>Valid expressions</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Return type</th> | ||||
|  | ||||
|       <th>Semantics</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Assignment</td> | ||||
|  | ||||
|       <td valign="top"><tt>t = u</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>T&</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>t</tt> is equivalent to <tt>u</tt></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Models</h3> | ||||
|  | ||||
|   <ul> | ||||
|     <li><tt>int</tt></li> | ||||
|  | ||||
|     <li><tt>std::pair</tt></li> | ||||
|   </ul> | ||||
|  | ||||
|   <h3>See also</h3> | ||||
|  | ||||
|   <p><a href= | ||||
|   "http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a> | ||||
|   and <a href="./CopyConstructible.html">CopyConstructible</a><br></p> | ||||
|   <hr> | ||||
|  | ||||
|   <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= | ||||
|   "http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" | ||||
|   height="31" width="88"></a></p> | ||||
|  | ||||
|   <p>Revised  | ||||
|   <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr valign="top"> | ||||
|       <td nowrap><i>Copyright © 2000</i></td> | ||||
|  | ||||
|       <td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of | ||||
|       Notre Dame (<a href= | ||||
|       "mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <p><i>Distributed under the Boost Software License, Version 1.0. (See | ||||
|   accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or | ||||
|   copy at <a href= | ||||
|   "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
							
								
								
									
										534
									
								
								Collection.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										534
									
								
								Collection.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,534 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <html> | ||||
| <head> | ||||
|   <meta http-equiv="Content-Language" content="en-us"> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> | ||||
|  | ||||
|   <title>Collection</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink= | ||||
| "#FF0000"> | ||||
|   <h1><img src="../../boost.png" alt="boost logo" width="277" align="middle" | ||||
|   height="86"><br> | ||||
|   Collection</h1> | ||||
|  | ||||
|   <h3>Description</h3> | ||||
|  | ||||
|   <p>A Collection is a <i>concept</i> similar to the STL <a href= | ||||
|   "http://www.sgi.com/tech/stl/Container.html">Container</a> concept. A | ||||
|   Collection provides iterators for accessing a range of elements and | ||||
|   provides information about the number of elements in the Collection. | ||||
|   However, a Collection has fewer requirements than a Container. The | ||||
|   motivation for the Collection concept is that there are many useful | ||||
|   Container-like types that do not meet the full requirements of Container, | ||||
|   and many algorithms that can be written with this reduced set of | ||||
|   requirements. To summarize the reduction in requirements:</p> | ||||
|  | ||||
|   <ul> | ||||
|     <li>It is not required to "own" its elements: the lifetime of an element | ||||
|     in a Collection does not have to match the lifetime of the Collection | ||||
|     object, though the lifetime of the element should cover the lifetime of | ||||
|     the Collection object.</li> | ||||
|  | ||||
|     <li>The semantics of copying a Collection object is not defined (it could | ||||
|     be a deep or shallow copy or not even support copying).</li> | ||||
|  | ||||
|     <li>The associated reference type of a Collection does not have to be a | ||||
|     real C++ reference.</li> | ||||
|   </ul>Because of the reduced requirements, some care must be taken when | ||||
|   writing code that is meant to be generic for all Collection types. In | ||||
|   particular, a Collection object should be passed by-reference since | ||||
|   assumptions can not be made about the behaviour of the copy constructor. | ||||
|  | ||||
|   <h3>Associated types</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <td valign="top">Value type</td> | ||||
|  | ||||
|       <td valign="top"><tt>X::value_type</tt></td> | ||||
|  | ||||
|       <td valign="top">The type of the object stored in a Collection. If the | ||||
|       Collection is <i>mutable</i> then the value type must be <a href= | ||||
|       "http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>. Otherwise | ||||
|       the value type must be <a href= | ||||
|       "./CopyConstructible.html">CopyConstructible</a>.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Iterator type</td> | ||||
|  | ||||
|       <td valign="top"><tt>X::iterator</tt></td> | ||||
|  | ||||
|       <td valign="top">The type of iterator used to iterate through a | ||||
|       Collection's elements. The iterator's value type is expected to be the | ||||
|       Collection's value type. A conversion from the iterator type to the | ||||
|       const iterator type must exist. The iterator type must be an <a href= | ||||
|       "http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Const iterator type</td> | ||||
|  | ||||
|       <td valign="top"><tt>X::const_iterator</tt></td> | ||||
|  | ||||
|       <td valign="top">A type of iterator that may be used to examine, but | ||||
|       not to modify, a Collection's elements.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Reference type</td> | ||||
|  | ||||
|       <td valign="top"><tt>X::reference</tt></td> | ||||
|  | ||||
|       <td valign="top">A type that behaves like a reference to the | ||||
|       Collection's value type. <a href="#n1">[1]</a></td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Const reference type</td> | ||||
|  | ||||
|       <td valign="top"><tt>X::const_reference</tt></td> | ||||
|  | ||||
|       <td valign="top">A type that behaves like a const reference to the | ||||
|       Collection's value type.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Pointer type</td> | ||||
|  | ||||
|       <td valign="top"><tt>X::pointer</tt></td> | ||||
|  | ||||
|       <td valign="top">A type that behaves as a pointer to the Collection's | ||||
|       value type.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Distance type</td> | ||||
|  | ||||
|       <td valign="top"><tt>X::difference_type</tt></td> | ||||
|  | ||||
|       <td valign="top">A signed integral type used to represent the distance | ||||
|       between two of the Collection's iterators. This type must be the same | ||||
|       as the iterator's distance type.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Size type</td> | ||||
|  | ||||
|       <td valign="top"><tt>X::size_type</tt></td> | ||||
|  | ||||
|       <td valign="top">An unsigned integral type that can represent any | ||||
|       nonnegative value of the Collection's distance type.</td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Notation</h3> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr> | ||||
|       <td valign="top"><tt>X</tt></td> | ||||
|  | ||||
|       <td valign="top">A type that is a model of Collection.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top"><tt>a</tt>, <tt>b</tt></td> | ||||
|  | ||||
|       <td valign="top">Object of type <tt>X</tt>.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top"><tt>T</tt></td> | ||||
|  | ||||
|       <td valign="top">The value type of <tt>X</tt>.</td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Valid expressions</h3> | ||||
|  | ||||
|   <p>The following expressions must be valid.</p> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Return type</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Beginning of range</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.begin()</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>iterator</tt> if <tt>a</tt> is mutable, | ||||
|       <tt>const_iterator</tt> otherwise</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">End of range</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.end()</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>iterator</tt> if <tt>a</tt> is mutable, | ||||
|       <tt>const_iterator</tt> otherwise</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Size</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.size()</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>size_type</tt></td> | ||||
|     </tr><!-- | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Maximum size | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>a.max_size()</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>size_type</tt> | ||||
| </TD> | ||||
| </TR> | ||||
| --> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Empty Collection</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.empty()</tt></td> | ||||
|  | ||||
|       <td valign="top">Convertible to <tt>bool</tt></td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Swap</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.swap(b)</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>void</tt></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Expression semantics</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Semantics</th> | ||||
|  | ||||
|       <th>Postcondition</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Beginning of range</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.begin()</tt></td> | ||||
|  | ||||
|       <td valign="top">Returns an iterator pointing to the first element in | ||||
|       the Collection.</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.begin()</tt> is either dereferenceable or | ||||
|       past-the-end. It is past-the-end if and only if <tt>a.size() == | ||||
|       0</tt>.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">End of range</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.end()</tt></td> | ||||
|  | ||||
|       <td valign="top">Returns an iterator pointing one past the last element | ||||
|       in the Collection.</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.end()</tt> is past-the-end.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Size</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.size()</tt></td> | ||||
|  | ||||
|       <td valign="top">Returns the size of the Collection, that is, its | ||||
|       number of elements.</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.size() >= 0</tt></td> | ||||
|     </tr><!-- | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Maximum size | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>a.max_size()</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
|   | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| Returns the largest size that this Collection can ever have. <A href="#8">[8]</A> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>a.max_size() >= 0 && a.max_size() >= a.size()</tt> | ||||
| </TD> | ||||
| </TR> | ||||
|  --> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Empty Collection</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.empty()</tt></td> | ||||
|  | ||||
|       <td valign="top">Equivalent to <tt>a.size() == 0</tt>. (But possibly | ||||
|       faster.)</td> | ||||
|  | ||||
|       <td valign="top"> </td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Swap</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.swap(b)</tt></td> | ||||
|  | ||||
|       <td valign="top">Equivalent to <tt>swap(a,b)</tt></td> | ||||
|  | ||||
|       <td valign="top"> </td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Complexity guarantees</h3> | ||||
|  | ||||
|   <p><tt>begin()</tt> and <tt>end()</tt> are amortized constant time.</p> | ||||
|  | ||||
|   <p><tt>size()</tt> is at most linear in the Collection's size. | ||||
|   <tt>empty()</tt> is amortized constant time.</p> | ||||
|  | ||||
|   <p><tt>swap()</tt> is at most linear in the size of the two | ||||
|   collections.</p> | ||||
|  | ||||
|   <h3>Invariants</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <td valign="top">Valid range</td> | ||||
|  | ||||
|       <td valign="top">For any Collection <tt>a</tt>, <tt>[a.begin(), | ||||
|       a.end())</tt> is a valid range.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Range size</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.size()</tt> is equal to the distance from | ||||
|       <tt>a.begin()</tt> to <tt>a.end()</tt>.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Completeness</td> | ||||
|  | ||||
|       <td valign="top">An algorithm that iterates through the range | ||||
|       <tt>[a.begin(), a.end())</tt> will pass through every element of | ||||
|       <tt>a</tt>.</td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Models</h3> | ||||
|  | ||||
|   <ul> | ||||
|     <li><tt>array</tt></li> | ||||
|  | ||||
|     <li><tt>array_ptr</tt></li> | ||||
|  | ||||
|     <li><tt>vector<bool></tt></li> | ||||
|   </ul> | ||||
|  | ||||
|   <h3>Collection Refinements</h3> | ||||
|  | ||||
|   <p>There are quite a few concepts that refine the Collection concept, | ||||
|   similar to the concepts that refine the Container concept. Here is a brief | ||||
|   overview of the refining concepts.</p> | ||||
|  | ||||
|   <h4>ForwardCollection</h4> | ||||
|  | ||||
|   <p>The elements are arranged in some order that does not change | ||||
|   spontaneously from one iteration to the next. As a result, a | ||||
|   ForwardCollection is <a href= | ||||
|   "http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a> | ||||
|   and <a href= | ||||
|   "http://www.sgi.com/tech/stl/LessThanComparable.html">LessThanComparable</a>. | ||||
|   In addition, the iterator type of a ForwardCollection is a | ||||
|   MultiPassInputIterator which is just an InputIterator with the added | ||||
|   requirements that the iterator can be used to make multiple passes through | ||||
|   a range, and that if <tt>it1 == it2</tt> and <tt>it1</tt> is | ||||
|   dereferenceable then <tt>++it1 == ++it2</tt>. The ForwardCollection also | ||||
|   has a <tt>front()</tt> method.</p> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Return type</th> | ||||
|  | ||||
|       <th>Semantics</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Front</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.front()</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable,<br> | ||||
|       <tt>const_reference</tt> otherwise.</td> | ||||
|  | ||||
|       <td valign="top">Equivalent to <tt>*(a.begin())</tt>.</td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h4>ReversibleCollection</h4> | ||||
|  | ||||
|   <p>The container provides access to iterators that traverse in both | ||||
|   directions (forward and reverse). The iterator type must meet all of the | ||||
|   requirements of <a href= | ||||
|   "http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a> | ||||
|   except that the reference type does not have to be a real C++ reference. | ||||
|   The ReversibleCollection adds the following requirements to those of | ||||
|   ForwardCollection.</p> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Return type</th> | ||||
|  | ||||
|       <th>Semantics</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Beginning of range</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.rbegin()</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>reverse_iterator</tt> if <tt>a</tt> is mutable, | ||||
|       <tt>const_reverse_iterator</tt> otherwise.</td> | ||||
|  | ||||
|       <td valign="top">Equivalent to | ||||
|       <tt>X::reverse_iterator(a.end())</tt>.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">End of range</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.rend()</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>reverse_iterator</tt> if <tt>a</tt> is mutable, | ||||
|       <tt>const_reverse_iterator</tt> otherwise.</td> | ||||
|  | ||||
|       <td valign="top">Equivalent to | ||||
|       <tt>X::reverse_iterator(a.begin())</tt>.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Back</td> | ||||
|  | ||||
|       <td valign="top"><tt>a.back()</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable,<br> | ||||
|       <tt>const_reference</tt> otherwise.</td> | ||||
|  | ||||
|       <td valign="top">Equivalent to <tt>*(--a.end())</tt>.</td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h4>SequentialCollection</h4> | ||||
|  | ||||
|   <p>The elements are arranged in a strict linear order. No extra methods are | ||||
|   required.</p> | ||||
|  | ||||
|   <h4>RandomAccessCollection</h4> | ||||
|  | ||||
|   <p>The iterators of a RandomAccessCollection satisfy all of the | ||||
|   requirements of <a href= | ||||
|   "http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a> | ||||
|   except that the reference type does not have to be a real C++ reference. In | ||||
|   addition, a RandomAccessCollection provides an element access operator.</p> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Return type</th> | ||||
|  | ||||
|       <th>Semantics</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Element Access</td> | ||||
|  | ||||
|       <td valign="top"><tt>a[n]</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable, | ||||
|       <tt>const_reference</tt> otherwise.</td> | ||||
|  | ||||
|       <td valign="top">Returns the nth element of the Collection. <tt>n</tt> | ||||
|       must be convertible to <tt>size_type</tt>. Precondition: <tt>0 <= n | ||||
|       < a.size()</tt>.</td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Notes</h3> | ||||
|  | ||||
|   <p><a name="n1" id="n1">[1]</a> The reference type does not have to be a | ||||
|   real C++ reference. The requirements of the reference type depend on the | ||||
|   context within which the Collection is being used. Specifically it depends | ||||
|   on the requirements the context places on the value type of the Collection. | ||||
|   The reference type of the Collection must meet the same requirements as the | ||||
|   value type. In addition, the reference objects must be equivalent to the | ||||
|   value type objects in the collection (which is trivially true if they are | ||||
|   the same object). Also, in a mutable Collection, an assignment to the | ||||
|   reference object must result in an assignment to the object in the | ||||
|   Collection (again, which is trivially true if they are the same object, but | ||||
|   non-trivial if the reference type is a proxy class).</p> | ||||
|  | ||||
|   <h3>See also</h3> | ||||
|  | ||||
|   <p><a href= | ||||
|   "http://www.sgi.com/tech/stl/Container.html">Container</a><br></p> | ||||
|   <hr> | ||||
|  | ||||
|   <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= | ||||
|   "http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" | ||||
|   height="31" width="88"></a></p> | ||||
|  | ||||
|   <p>Revised  | ||||
|   <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 | ||||
|   December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr valign="top"> | ||||
|       <td nowrap><i>Copyright © 2000</i></td> | ||||
|  | ||||
|       <td><i><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy | ||||
|       Siek</a>, Univ.of Notre Dame and C++ Library & Compiler Group/SGI | ||||
|       (<a href="mailto:jsiek@engr.sgi.com">jsiek@engr.sgi.com</a>)</i></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <p><i>Distributed under the Boost Software License, Version 1.0. (See | ||||
|   accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or | ||||
|   copy at <a href= | ||||
|   "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,178 +1,139 @@ | ||||
| <HTML> | ||||
| <!-- | ||||
|   -- Copyright (c) Jeremy Siek 2000 | ||||
|   -- | ||||
|   -- Permission to use, copy, modify, distribute and sell this software | ||||
|   -- and its documentation for any purpose is hereby granted without fee, | ||||
|   -- provided that the above copyright notice appears in all copies and | ||||
|   -- that both that copyright notice and this permission notice appear | ||||
|   -- in supporting documentation.  Silicon Graphics makes no | ||||
|   -- representations about the suitability of this software for any | ||||
|   -- purpose.  It is provided "as is" without express or implied warranty. | ||||
|   --> | ||||
| <Head> | ||||
| <Title>CopyConstructible</Title> | ||||
| </HEAD> | ||||
| <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"  | ||||
|         ALINK="#ff0000">  | ||||
| <IMG SRC="../../c++boost.gif"  | ||||
|      ALT="C++ Boost" width="277" height="86">  | ||||
| <!--end header--> | ||||
| <BR Clear> | ||||
| <H1>CopyConstructible</H1> | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <h3>Description</h3> | ||||
| A type is CopyConstructible if it is possible to copy objects of that | ||||
| type. | ||||
| <html> | ||||
| <head> | ||||
|   <meta http-equiv="Content-Language" content="en-us"> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> | ||||
|  | ||||
| <h3>Notation</h3> | ||||
| <Table> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| <tt>T</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| is type that is a model of CopyConstructible | ||||
| </TD> | ||||
| </TR> | ||||
|   <title>Copy Constructible</title> | ||||
| </head> | ||||
|  | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| <tt>t</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| is an object of type <tt>T</tt> | ||||
| </TD> | ||||
| </tr> | ||||
| <body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink= | ||||
| "#FF0000"> | ||||
|   <img src="../../boost.png" alt="C++ Boost" width="277" height= | ||||
|   "86"><br clear="none"> | ||||
|  | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| <tt>u</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| is an object of type <tt>const T</tt> | ||||
| </TD> | ||||
| </tr> | ||||
|   <h1>Copy Constructible</h1> | ||||
|  | ||||
| </table> | ||||
| <h3>Definitions</h3> | ||||
| <h3>Valid expressions</h3> | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH> | ||||
| Name | ||||
| </TH> | ||||
| <TH> | ||||
| Expression | ||||
| </TH> | ||||
| <TH> | ||||
| Return type | ||||
| </TH> | ||||
| <TH> | ||||
| Semantics | ||||
| </TH> | ||||
| </TR> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Copy constructor | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>T(t)</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>T</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>t</tt> is equivalent to <tt>T(t)</tt> | ||||
| </TD> | ||||
| </TR> | ||||
|   <h3>Description</h3> | ||||
|  | ||||
|   <p>A type is Copy Constructible if it is possible to copy objects of that | ||||
|   type.</p> | ||||
|  | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Copy constructor | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <pre> | ||||
|   <h3>Notation</h3> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr> | ||||
|       <td valign="top"><tt>T</tt></td> | ||||
|  | ||||
|       <td valign="top">is type that is a model of Copy Constructible</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top"><tt>t</tt></td> | ||||
|  | ||||
|       <td valign="top">is an object of type <tt>T</tt></td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top"><tt>u</tt></td> | ||||
|  | ||||
|       <td valign="top">is an object of type <tt>const T</tt></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Definitions</h3> | ||||
|  | ||||
|   <h3>Valid expressions</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Return type</th> | ||||
|  | ||||
|       <th>Semantics</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Copy constructor</td> | ||||
|  | ||||
|       <td valign="top"><tt>T(t)</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>T</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>t</tt> is equivalent to <tt>T(t)</tt></td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Copy constructor</td> | ||||
|  | ||||
|       <td valign="top"> | ||||
|         <pre> | ||||
| T(u) | ||||
| </pre> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>T</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>u</tt> is equivalent to <tt>T(u)</tt> | ||||
| </TD> | ||||
| </TR> | ||||
|       </td> | ||||
|  | ||||
|       <td valign="top"><tt>T</tt></td> | ||||
|  | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Destructor | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <pre> | ||||
|       <td valign="top"><tt>u</tt> is equivalent to <tt>T(u)</tt></td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Destructor</td> | ||||
|  | ||||
|       <td valign="top"> | ||||
|         <pre> | ||||
| t.~T() | ||||
| </pre> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>T</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
|   | ||||
| </TD> | ||||
| </TR> | ||||
|       </td> | ||||
|  | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Address Operator | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <pre> | ||||
|       <td valign="top"><tt>T</tt></td> | ||||
|  | ||||
|       <td valign="top"> </td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Address Operator</td> | ||||
|  | ||||
|       <td valign="top"> | ||||
|         <pre> | ||||
| &t | ||||
| </pre> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>T*</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| denotes the address of <tt>t</tt> | ||||
| </TD> | ||||
| </TR> | ||||
|       </td> | ||||
|  | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Address Operator | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <pre> | ||||
|       <td valign="top"><tt>T*</tt></td> | ||||
|  | ||||
|       <td valign="top">denotes the address of <tt>t</tt></td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Address Operator</td> | ||||
|  | ||||
|       <td valign="top"> | ||||
|         <pre> | ||||
| &u | ||||
| </pre> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>T*</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| denotes the address of <tt>u</tt> | ||||
| </TD> | ||||
| </TR> | ||||
|       </td> | ||||
|  | ||||
|       <td valign="top"><tt>T*</tt></td> | ||||
|  | ||||
|       <td valign="top">denotes the address of <tt>u</tt></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
| </table> | ||||
|   <h3>Models</h3> | ||||
|  | ||||
|   <ul> | ||||
|     <li><tt>int</tt></li> | ||||
|  | ||||
| </table> | ||||
| <h3>Models</h3> | ||||
|     <li><tt>std::pair</tt></li> | ||||
|   </ul> | ||||
|  | ||||
| <UL> | ||||
| <LI><tt>int</tt> | ||||
| <LI><tt>std::pair</tt> | ||||
| </UL> | ||||
|  | ||||
| <h3>Concept Checking Class</h3> | ||||
|  | ||||
| <pre> | ||||
|   <h3>Concept Checking Class</h3> | ||||
|   <pre> | ||||
|   template <class T> | ||||
|   struct CopyConstructibleConcept | ||||
|   { | ||||
| @@ -192,19 +153,33 @@ denotes the address of <tt>u</tt> | ||||
|   }; | ||||
| </pre> | ||||
|  | ||||
| <h3>See also</h3> | ||||
| <A | ||||
| href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">DefaultConstructible</A> | ||||
| and  | ||||
| <A href="http://www.sgi.com/Technology/STL/Assignable.html">Assignable</A> | ||||
|   <h3>See also</h3> | ||||
|  | ||||
| <br> | ||||
| <HR> | ||||
| <TABLE> | ||||
| <TR valign=top> | ||||
| <TD nowrap>Copyright © 2000</TD><TD> | ||||
| <A HREF=http://www.lsc.nd.edu/~jsiek>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>) | ||||
| </TD></TR></TABLE> | ||||
|   <p><a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default | ||||
|   Constructible</a> and <a href="./Assignable.html">Assignable</a><br></p> | ||||
|   <hr> | ||||
|  | ||||
| </BODY> | ||||
| </HTML>  | ||||
|   <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= | ||||
|   "http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" | ||||
|   height="31" width="88"></a></p> | ||||
|  | ||||
|   <p>Revised  | ||||
|   <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 | ||||
|   December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr valign="top"> | ||||
|       <td nowrap><i>Copyright © 2000</i></td> | ||||
|  | ||||
|       <td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of | ||||
|       Notre Dame (<a href= | ||||
|       "mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <p><i>Distributed under the Boost Software License, Version 1.0. (See | ||||
|   accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or | ||||
|   copy at <a href= | ||||
|   "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
| @@ -1,212 +1,210 @@ | ||||
| <HTML> | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <html> | ||||
| <!-- | ||||
|   -- Copyright (c) Jeremy Siek 2000 | ||||
|   -- | ||||
|   -- Permission to use, copy, modify, distribute and sell this software | ||||
|   -- and its documentation for any purpose is hereby granted without fee, | ||||
|   -- provided that the above copyright notice appears in all copies and | ||||
|   -- that both that copyright notice and this permission notice appear | ||||
|   -- in supporting documentation.  Silicon Graphics makes no | ||||
|   -- representations about the suitability of this software for any | ||||
|   -- purpose.  It is provided "as is" without express or implied warranty. | ||||
|   == Copyright (c) 1996-1999 | ||||
|   == Silicon Graphics Computer Systems, Inc. | ||||
|   == | ||||
|   == Permission to use, copy, modify, distribute and sell this software | ||||
|   == and its documentation for any purpose is hereby granted without fee, | ||||
|   == provided that the above copyright notice appears in all copies and | ||||
|   == that both that copyright notice and this permission notice appear | ||||
|   == in supporting documentation.  Silicon Graphics makes no | ||||
|   == representations about the suitability of this software for any | ||||
|   == purpose.  It is provided "as is" without express or implied warranty. | ||||
|   == | ||||
|   == Copyright (c) 1994 | ||||
|   == Hewlett-Packard Company | ||||
|   == | ||||
|   == Permission to use, copy, modify, distribute and sell this software | ||||
|   == and its documentation for any purpose is hereby granted without fee, | ||||
|   == provided that the above copyright notice appears in all copies and | ||||
|   == that both that copyright notice and this permission notice appear | ||||
|   == in supporting documentation.  Hewlett-Packard Company makes no | ||||
|   == representations about the suitability of this software for any | ||||
|   == purpose.  It is provided "as is" without express or implied warranty. | ||||
|   == | ||||
|   --> | ||||
| <!-- | ||||
|   -- Copyright (c) 1996-1999 | ||||
|   -- Silicon Graphics Computer Systems, Inc. | ||||
|   -- | ||||
|   -- Permission to use, copy, modify, distribute and sell this software | ||||
|   -- and its documentation for any purpose is hereby granted without fee, | ||||
|   -- provided that the above copyright notice appears in all copies and | ||||
|   -- that both that copyright notice and this permission notice appear | ||||
|   -- in supporting documentation.  Silicon Graphics makes no | ||||
|   -- representations about the suitability of this software for any | ||||
|   -- purpose.  It is provided "as is" without express or implied warranty. | ||||
|   -- | ||||
|   -- Copyright (c) 1994 | ||||
|   -- Hewlett-Packard Company | ||||
|   -- | ||||
|   -- Permission to use, copy, modify, distribute and sell this software | ||||
|   -- and its documentation for any purpose is hereby granted without fee, | ||||
|   -- provided that the above copyright notice appears in all copies and | ||||
|   -- that both that copyright notice and this permission notice appear | ||||
|   -- in supporting documentation.  Hewlett-Packard Company makes no | ||||
|   -- representations about the suitability of this software for any | ||||
|   -- purpose.  It is provided "as is" without express or implied warranty. | ||||
|   -- | ||||
|   --> | ||||
| <Head> | ||||
| <Title>LessThanComparable</Title> | ||||
| </Head> | ||||
| <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"  | ||||
|         ALINK="#ff0000">  | ||||
| <IMG SRC="../../c++boost.gif"  | ||||
|      ALT="C++ Boost" width="277" height="86">  | ||||
| <!--end header--> | ||||
| <BR Clear> | ||||
| <H1>LessThanComparable</H1> | ||||
|  | ||||
| <h3>Description</h3> | ||||
| A type is LessThanComparable if it is ordered: it must | ||||
| be possible to compare two objects of that type using <tt>operator<</tt>, and | ||||
| <tt>operator<</tt> must be a strict weak ordering relation. | ||||
| <head> | ||||
|   <meta http-equiv="Content-Language" content="en-us"> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> | ||||
|  | ||||
|   <title>LessThanComparable</title> | ||||
| </head> | ||||
|  | ||||
| <h3>Refinement of</h3> | ||||
| <h3>Associated types</h3> | ||||
| <h3>Notation</h3> | ||||
| <Table> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| <tt>X</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| A type that is a model of LessThanComparable | ||||
| </TD> | ||||
| </TR> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| <tt>x</tt>, <tt>y</tt>, <tt>z</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| Object of type <tt>X</tt> | ||||
| </TD> | ||||
| </tr> | ||||
| </table> | ||||
| <h3>Definitions</h3> | ||||
| Consider the relation <tt>!(x < y) && !(y < x)</tt>.  If this relation is | ||||
| transitive (that is, if <tt>!(x < y) && !(y < x) && !(y < z) && !(z < y)</tt> | ||||
| implies <tt>!(x < z) && !(z < x)</tt>), then it satisfies the mathematical | ||||
| definition of an equivalence relation.  In this case, <tt>operator<</tt> | ||||
| is a <i>strict weak ordering</i>. | ||||
| <P> | ||||
| If <tt>operator<</tt> is a strict weak ordering, and if each equivalence class | ||||
| has only a single element, then <tt>operator<</tt> is a <i>total ordering</i>. | ||||
| <h3>Valid expressions</h3> | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH> | ||||
| Name | ||||
| </TH> | ||||
| <TH> | ||||
| Expression | ||||
| </TH> | ||||
| <TH> | ||||
| Type requirements | ||||
| </TH> | ||||
| <TH> | ||||
| Return type | ||||
| </TH> | ||||
| </TR> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Less | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>x < y</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
|   | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| Convertible to <tt>bool</tt> | ||||
| </TD> | ||||
| </TR> | ||||
| </table> | ||||
| <body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink= | ||||
| "#FF0000"> | ||||
|   <img src="../../boost.png" alt="C++ Boost" width="277" height= | ||||
|   "86"><br clear="none"> | ||||
|  | ||||
|   <h1>LessThanComparable</h1> | ||||
|  | ||||
|   <h3>Description</h3> | ||||
|  | ||||
| <h3>Expression semantics</h3> | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH> | ||||
| Name | ||||
| </TH> | ||||
| <TH> | ||||
| Expression | ||||
| </TH> | ||||
| <TH> | ||||
| Precondition | ||||
| </TH> | ||||
| <TH> | ||||
| Semantics | ||||
| </TH> | ||||
| <TH> | ||||
| Postcondition | ||||
| </TH> | ||||
| </TR> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Less | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>x < y</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>x</tt> and <tt>y</tt> are in the domain of <tt><</tt> | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
|   | ||||
| </TD> | ||||
| </table> | ||||
|   <p>A type is LessThanComparable if it is ordered: it must be possible to | ||||
|   compare two objects of that type using <tt>operator<</tt>, and | ||||
|   <tt>operator<</tt> must be a strict weak ordering relation.</p> | ||||
|  | ||||
|   <h3>Refinement of</h3> | ||||
|  | ||||
| <h3>Complexity guarantees</h3> | ||||
| <h3>Invariants</h3> | ||||
| <Table border> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Irreflexivity | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>x < x</tt> must be false. | ||||
| </TD> | ||||
| </TR> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Antisymmetry | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>x < y</tt> implies !(y < x) <A href="#2">[2]</A> | ||||
| </TD> | ||||
| </TR> | ||||
| <TR> | ||||
| <TD VAlign=top> | ||||
| Transitivity | ||||
| </TD> | ||||
| <TD VAlign=top> | ||||
| <tt>x < y</tt> and <tt>y < z</tt> implies <tt>x < z</tt> <A href="#3">[3]</A> | ||||
| </TD> | ||||
| </tr> | ||||
| </table> | ||||
| <h3>Models</h3> | ||||
| <UL> | ||||
| <LI> | ||||
| int | ||||
| </UL> | ||||
| <h3>Notes</h3> | ||||
| <P><A name="1">[1]</A> | ||||
| Only <tt>operator<</tt> is fundamental; the other inequality operators | ||||
| are essentially syntactic sugar. | ||||
| <P><A name="2">[2]</A> | ||||
| Antisymmetry is a theorem, not an axiom: it follows from | ||||
| irreflexivity and transitivity. | ||||
| <P><A name="3">[3]</A> | ||||
| Because of irreflexivity and transitivity, <tt>operator<</tt> always | ||||
| satisfies the definition of a <i>partial ordering</i>.  The definition of | ||||
| a <i>strict weak ordering</i> is stricter, and the definition of a | ||||
| <i>total ordering</i> is stricter still. | ||||
| <h3>See also</h3> | ||||
| <A href="http://www.sgi.com/Technology/STL/EqualityComparable.html">EqualityComparable</A>, <A href="http://www.sgi.com/Technology/STL/StrictWeakOrdering.html">StrictWeakOrdering</A> | ||||
|   <h3>Associated types</h3> | ||||
|  | ||||
|   <h3>Notation</h3> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr> | ||||
|       <td valign="top"><tt>X</tt></td> | ||||
|  | ||||
| <br> | ||||
| <HR> | ||||
| <TABLE> | ||||
| <TR valign=top> | ||||
| <TD nowrap>Copyright © 2000</TD><TD> | ||||
| <A HREF=http://www.lsc.nd.edu/~jsiek>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>) | ||||
| </TD></TR></TABLE> | ||||
|       <td valign="top">A type that is a model of LessThanComparable</td> | ||||
|     </tr> | ||||
|  | ||||
| </BODY> | ||||
| </HTML>  | ||||
|     <tr> | ||||
|       <td valign="top"><tt>x</tt>, <tt>y</tt>, <tt>z</tt></td> | ||||
|  | ||||
|       <td valign="top">Object of type <tt>X</tt></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Definitions</h3> | ||||
|  | ||||
|   <p>Consider the relation <tt>!(x < y) && !(y < x)</tt>. If | ||||
|   this relation is transitive (that is, if <tt>!(x < y) && !(y | ||||
|   < x) && !(y < z) && !(z < y)</tt> implies <tt>!(x | ||||
|   < z) && !(z < x)</tt>), then it satisfies the mathematical | ||||
|   definition of an equivalence relation. In this case, <tt>operator<</tt> | ||||
|   is a <i>strict weak ordering</i>.</p> | ||||
|  | ||||
|   <p>If <tt>operator<</tt> is a strict weak ordering, and if each | ||||
|   equivalence class has only a single element, then <tt>operator<</tt> is | ||||
|   a <i>total ordering</i>.</p> | ||||
|  | ||||
|   <h3>Valid expressions</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Type requirements</th> | ||||
|  | ||||
|       <th>Return type</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Less</td> | ||||
|  | ||||
|       <td valign="top"><tt>x < y</tt></td> | ||||
|  | ||||
|       <td valign="top"> </td> | ||||
|  | ||||
|       <td valign="top">Convertible to <tt>bool</tt></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Expression semantics</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Name</th> | ||||
|  | ||||
|       <th>Expression</th> | ||||
|  | ||||
|       <th>Precondition</th> | ||||
|  | ||||
|       <th>Semantics</th> | ||||
|  | ||||
|       <th>Postcondition</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Less</td> | ||||
|  | ||||
|       <td valign="top"><tt>x < y</tt></td> | ||||
|  | ||||
|       <td valign="top"><tt>x</tt> and <tt>y</tt> are in the domain of | ||||
|       <tt><</tt></td> | ||||
|  | ||||
|       <td valign="top"> </td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Complexity guarantees</h3> | ||||
|  | ||||
|   <h3>Invariants</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <td valign="top">Irreflexivity</td> | ||||
|  | ||||
|       <td valign="top"><tt>x < x</tt> must be false.</td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Antisymmetry</td> | ||||
|  | ||||
|       <td valign="top"><tt>x < y</tt> implies !(y < x) <a href= | ||||
|       "#n2">[2]</a></td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td valign="top">Transitivity</td> | ||||
|  | ||||
|       <td valign="top"><tt>x < y</tt> and <tt>y < z</tt> implies <tt>x | ||||
|       < z</tt> <a href="#n3">[3]</a></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Models</h3> | ||||
|  | ||||
|   <ul> | ||||
|     <li>int</li> | ||||
|   </ul> | ||||
|  | ||||
|   <h3>Notes</h3> | ||||
|  | ||||
|   <p><a name="n1" id="n1">[1]</a> Only <tt>operator<</tt> is fundamental; | ||||
|   the other inequality operators are essentially syntactic sugar.</p> | ||||
|  | ||||
|   <p><a name="n2" id="n2">[2]</a> Antisymmetry is a theorem, not an axiom: it | ||||
|   follows from irreflexivity and transitivity.</p> | ||||
|  | ||||
|   <p><a name="n3" id="n3">[3]</a> Because of irreflexivity and transitivity, | ||||
|   <tt>operator<</tt> always satisfies the definition of a <i>partial | ||||
|   ordering</i>. The definition of a <i>strict weak ordering</i> is stricter, | ||||
|   and the definition of a <i>total ordering</i> is stricter still.</p> | ||||
|  | ||||
|   <h3>See also</h3> | ||||
|  | ||||
|   <p><a href= | ||||
|   "http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a>, | ||||
|   <a href= | ||||
|   "http://www.sgi.com/tech/stl/StrictWeakOrdering.html">StrictWeakOrdering</a><br> | ||||
|   </p> | ||||
|   <hr> | ||||
|  | ||||
|   <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= | ||||
|   "http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" | ||||
|   height="31" width="88"></a></p> | ||||
|  | ||||
|   <p>Revised  | ||||
|   <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 | ||||
|   December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr valign="top"> | ||||
|       <td nowrap><i>Copyright © 2000</i></td> | ||||
|  | ||||
|       <td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of | ||||
|       Notre Dame (<a href= | ||||
|       "mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <p><i>Distributed under the Boost Software License, Version 1.0. (See | ||||
|   accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or | ||||
|   copy at <a href= | ||||
|   "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
| @@ -1,92 +1,95 @@ | ||||
| <HTML> | ||||
| <!-- | ||||
|   -- Copyright (c) Jeremy Siek 2000 | ||||
|   -- | ||||
|   -- Permission to use, copy, modify, distribute and sell this software | ||||
|   -- and its documentation for any purpose is hereby granted without fee, | ||||
|   -- provided that the above copyright notice appears in all copies and | ||||
|   -- that both that copyright notice and this permission notice appear | ||||
|   -- in supporting documentation.  Silicon Graphics makes no | ||||
|   -- representations about the suitability of this software for any | ||||
|   -- purpose.  It is provided "as is" without express or implied warranty. | ||||
|   --> | ||||
| <Head> | ||||
| <Title>MultiPassInputIterator</Title> | ||||
| <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"  | ||||
| 	ALINK="#ff0000">  | ||||
| <IMG SRC="../../c++boost.gif"  | ||||
|      ALT="C++ Boost" width="277" height="86">  | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <BR Clear> | ||||
| <html> | ||||
| <head> | ||||
|   <meta http-equiv="Content-Language" content="en-us"> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> | ||||
|  | ||||
| <H2> | ||||
| <A NAME="concept:MultiPassInputIterator"></A> | ||||
| MultiPassInputIterator | ||||
| </H2> | ||||
|   <title>MultiPassInputIterator</title> | ||||
| </head> | ||||
|  | ||||
| This concept is a refinement of <a | ||||
| href="http://www.sgi.com/Technology/STL/InputIterator.html">InputIterator</a>, | ||||
| adding the requirements that the iterator can be used to make multiple | ||||
| passes through a range, and that if <TT>it1 == it2</TT> and | ||||
| <TT>it1</TT> is dereferenceable then <TT>++it1 == ++it2</TT>. The | ||||
| MultiPassInputIterator is very similar to the <a | ||||
| href="http://www.sgi.com/Technology/STL/ForwardIterator.hmtl">ForwardIterator</a>. The | ||||
| only difference is that a <a | ||||
| href="http://www.sgi.com/Technology/STL/ForwardIterator.hmtl">ForwardIterator</a> | ||||
| requires the <TT>reference</TT> type to be <TT>value_type&</TT>, whereas | ||||
| MultiPassInputIterator is like <a | ||||
| href="http://www.sgi.com/Technology/STL/InputIterator.html">InputIterator</a> | ||||
| in that the <TT>reference</TT> type merely has to be convertible to | ||||
| <TT>value_type</TT>. | ||||
| <body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink= | ||||
| "#FF0000"> | ||||
|   <img src="../../boost.png" alt="C++ Boost" width="277" height= | ||||
|   "86"><br clear="none"> | ||||
|  | ||||
|   <h2><a name="concept:MultiPassInputIterator" id= | ||||
|   "concept:MultiPassInputIterator"></a> Multi-Pass Input Iterator</h2> | ||||
|  | ||||
| <h3>Design Notes</h3> | ||||
|   <p>This concept is a refinement of <a href= | ||||
|   "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>, adding | ||||
|   the requirements that the iterator can be used to make multiple passes | ||||
|   through a range, and that if <tt>it1 == it2</tt> and <tt>it1</tt> is | ||||
|   dereferenceable then <tt>++it1 == ++it2</tt>. The Multi-Pass Input Iterator | ||||
|   is very similar to the <a href= | ||||
|   "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>. | ||||
|   The only difference is that a <a href= | ||||
|   "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a> | ||||
|   requires the <tt>reference</tt> type to be <tt>value_type&</tt>, | ||||
|   whereas MultiPassInputIterator is like <a href= | ||||
|   "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a> in that | ||||
|   the <tt>reference</tt> type merely has to be convertible to | ||||
|   <tt>value_type</tt>.</p> | ||||
|  | ||||
| comments by Valentin Bonnard: | ||||
|   <h3>Design Notes</h3> | ||||
|  | ||||
| <p> I think that introducing MultiPassInputIterator isn't the right | ||||
| solution. Do you also want to define MultiPassBidirectionnalIterator | ||||
| and MultiPassRandomAccessIterator ? I don't, definitly. It only | ||||
| confuses the issue. The problem lies into the existing hierarchy of | ||||
| iterators, which mixes movabillity, modifiabillity and lvalue-ness, | ||||
| and these are clearly independant. | ||||
|   <p>comments by Valentin Bonnard:</p> | ||||
|  | ||||
| <p> The terms Forward, Bidirectionnal and RandomAccess are about | ||||
| movabillity and shouldn't be used to mean anything else.  In a | ||||
| completly orthogonal way, iterators can be immutable, mutable, or | ||||
| neither.  Lvalueness of iterators is also orthogonal with | ||||
| immutabillity.  With these clean concepts, your MultiPassInputIterator | ||||
| is just called a ForwardIterator. | ||||
|   <p>I think that introducing Multi-Pass Input Iterator isn't the right | ||||
|   solution. Do you also want to define Multi-Pass Bidirectionnal Iterator and | ||||
|   Multi-Pass Random Access Iterator ? I don't, definitly. It only confuses | ||||
|   the issue. The problem lies into the existing hierarchy of iterators, which | ||||
|   mixes movabillity, modifiabillity and lvalue-ness, and these are clearly | ||||
|   independant.</p> | ||||
|  | ||||
| <p>                 | ||||
| Other translations are:<br> | ||||
| std::ForwardIterator -> ForwardIterator & LvalueIterator<br> | ||||
| std::BidirectionnalIterator -> BidirectionnalIterator & LvalueIterator<br> | ||||
| std::RandomAccessIterator -> RandomAccessIterator & LvalueIterator<br> | ||||
|   <p>The terms Forward, Bidirectionnal and Random Access are about | ||||
|   movabillity and shouldn't be used to mean anything else. In a completly | ||||
|   orthogonal way, iterators can be immutable, mutable, or neither. Lvalueness | ||||
|   of iterators is also orthogonal with immutabillity. With these clean | ||||
|   concepts, your Multi-Pass Input Iterator is just called a Forward | ||||
|   Iterator.</p> | ||||
|  | ||||
| <p> | ||||
| Note that in practice the only operation not allowed on my  | ||||
| ForwardIterator which is allowed on std::ForwardIterator is  | ||||
| <tt>&*it</tt>. I think that <tt>&*</tt> is rarely needed in generic code. | ||||
|   <p>Other translations are:<br> | ||||
|   std::Forward Iterator -> ForwardIterator & Lvalue Iterator<br> | ||||
|   std::Bidirectionnal Iterator -> Bidirectionnal Iterator & Lvalue | ||||
|   Iterator<br> | ||||
|   std::Random Access Iterator -> Random Access Iterator & Lvalue | ||||
|   Iterator<br></p> | ||||
|  | ||||
| <p> | ||||
| reply by Jeremy Siek: | ||||
|   <p>Note that in practice the only operation not allowed on my Forward | ||||
|   Iterator which is allowed on std::Forward Iterator is <tt>&*it</tt>. I | ||||
|   think that <tt>&*</tt> is rarely needed in generic code.</p> | ||||
|  | ||||
| <p> | ||||
| The above analysis by Valentin is right on. Of course, there is | ||||
| the problem with backward compatibility. The current STL implementations | ||||
| are based on the old definition of ForwardIterator. The right course | ||||
| of action is to get ForwardIterator, etc. changed in the C++ standard. | ||||
| Once that is done we can drop MultiPassInputIterator. | ||||
|   <p>reply by Jeremy Siek:</p> | ||||
|  | ||||
|   <p>The above analysis by Valentin is right on. Of course, there is the | ||||
|   problem with backward compatibility. The current STL implementations are | ||||
|   based on the old definition of Forward Iterator. The right course of action | ||||
|   is to get Forward Iterator, etc. changed in the C++ standard. Once that is | ||||
|   done we can drop Multi-Pass Input Iterator.<br></p> | ||||
|   <hr> | ||||
|  | ||||
| <br> | ||||
| <HR> | ||||
| <TABLE> | ||||
| <TR valign=top> | ||||
| <TD nowrap>Copyright © 2000</TD><TD> | ||||
| <A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>) | ||||
| </TD></TR></TABLE> | ||||
|   <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= | ||||
|   "http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" | ||||
|   height="31" width="88"></a></p> | ||||
|  | ||||
| </BODY> | ||||
| </HTML>  | ||||
|   <p>Revised  | ||||
|   <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 | ||||
|   December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p> | ||||
|  | ||||
|   <table summary=""> | ||||
|     <tr valign="top"> | ||||
|       <td nowrap><i>Copyright © 2000</i></td> | ||||
|  | ||||
|       <td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of | ||||
|       Notre Dame (<a href= | ||||
|       "mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <p><i>Distributed under the Boost Software License, Version 1.0. (See | ||||
|   accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or | ||||
|   copy at <a href= | ||||
|   "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
							
								
								
									
										164
									
								
								OptionalPointee.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								OptionalPointee.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| <HTML> | ||||
| <Head> | ||||
| <Title>OptionalPointee Concept</Title> | ||||
| </HEAD> | ||||
| <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"  | ||||
|         ALINK="#ff0000">  | ||||
| <IMG SRC="../../boost.png"  | ||||
|      ALT="C++ Boost" width="277" height="86">  | ||||
| <!--end header--> | ||||
| <BR Clear> | ||||
| <H1>Concept: OptionalPointee</H1> | ||||
|  | ||||
| <h3>Description</h3> | ||||
| A type is a model of <i>OptionalPointee</i> if it points to (or refers to) a value  | ||||
| that may not exist. That is, if it has a <b>pointee</b> which might be <b>valid</b> | ||||
| (existent) or <b>invalid</b> (inexistent); and it is possible to test whether the  | ||||
| pointee is valid or not. | ||||
| This model does <u>not</u> imply pointer semantics: i.e., it does not imply shallow copy nor | ||||
| aliasing. | ||||
| <h3>Notation</h3> | ||||
| <Table> | ||||
|   <TR> | ||||
|     <TD VAlign=top> <tt>T</tt> </TD> | ||||
|     <TD VAlign=top> is a type that is a model of OptionalPointee</TD> | ||||
|   </TR> | ||||
|   <TR> | ||||
|     <TD VAlign=top> <tt>t</tt> </TD> | ||||
|     <TD VAlign=top> is an object of type <tt>T</tt> or possibly <tt>const T</tt></TD> | ||||
|   </tr> | ||||
| </table> | ||||
| <h3>Definitions</h3> | ||||
| <h3>Valid expressions</h3> | ||||
| <Table border> | ||||
|   <TR> | ||||
|     <TH> Name </TH> | ||||
|     <TH> Expression </TH> | ||||
|     <TH> Return type </TH> | ||||
|     <TH> Semantics </TH> | ||||
|   </TR> | ||||
|   <TR> | ||||
|     <TD VAlign=top>Value Access</TD> | ||||
|     <TD VAlign=top> <tt>*t</tt></TD> | ||||
|     <TD VAlign=top> <tt>T&</tt></TD> | ||||
|     <TD VAlign=top>If the pointee is valid returns a reference to | ||||
|       the pointee.<br> | ||||
|       If the pointee is invalid the result is <i>undefined</i>.</TD> | ||||
|     <TD VAlign=top> </TD> | ||||
|   </TR> | ||||
|   <TR> | ||||
|     <TD VAlign=top>Value Access</TD> | ||||
|     <TD VAlign=top> <tt>t-><i>xyz</i></tt></TD> | ||||
|     <TD VAlign=top> <tt>T*</tt></TD> | ||||
|     <TD VAlign=top>If the pointee is valid returns a builtin pointer to the pointee.<br> | ||||
|       If the pointee is invalid the result is <i>undefined</i> (It might not even return NULL).<br> | ||||
|     </TD> | ||||
|     <TD VAlign=top> </TD> | ||||
|   </TR> | ||||
|   <TR> | ||||
|     <TD VAlign=top>Validity Test</TD> | ||||
|     <TD VAlign=top> <tt>t</tt><br> | ||||
|       <tt>t != 0</tt><br> | ||||
|       <tt>!!t</tt> | ||||
|      </TD> | ||||
|     <TD VAlign=top> bool </TD> | ||||
|     <TD VAlign=top>If the pointee is valid returns true.<br> | ||||
|       If the pointee is invalid returns false.</TD> | ||||
|     <TD VAlign=top></TD> | ||||
|   </TR> | ||||
|   <TR> | ||||
|     <TD VAlign=top>Invalidity Test</TD> | ||||
|     <TD VAlign=top> <tt>t == 0</tt><br> | ||||
|                     <tt>!t</tt> | ||||
|     </TD> | ||||
|     <TD VAlign=top> bool </TD> | ||||
|     <TD VAlign=top>If the pointee is valid returns false.<br> | ||||
|       If the pointee is invalid returns true.</TD> | ||||
|     <TD VAlign=top></TD> | ||||
|   </TR> | ||||
| </table> | ||||
|  | ||||
|  | ||||
| <h3>Models</h3> | ||||
|  | ||||
| <UL> | ||||
|   <LI><tt>pointers, both builtin and smart.</tt> | ||||
|   <LI><tt>boost::optional<></tt> | ||||
| </UL> | ||||
|  | ||||
| <HR> | ||||
| <h3>OptionalPointee and relational operations</h3> | ||||
| <p>This concept does not define any particular semantic for relational operations, therefore, | ||||
| a type which models this concept might have either shallow or deep relational semantics.<br> | ||||
| For instance, pointers, which are models of OptionalPointee, have shallow relational operators: | ||||
| comparisons of pointers do not involve comparisons of pointees. | ||||
| This makes sense for pointers because they have shallow copy semantics.<br> | ||||
| But boost::optional<T>, on the other hand, which is also a model of OptionalPointee, has | ||||
| deep-copy and deep-relational semantics.<br> | ||||
| If generic code is written for this concept, it is important not to use relational | ||||
| operators directly because the semantics might be different depending on the actual type.<br> | ||||
| Still, the concept itsef can be used to define <i>deep</i> relational tests that can | ||||
| be used in generic code with any type which models OptionalPointee:</p> | ||||
| <a name="equal"></a> | ||||
| <p><u>Equivalence relation:</u></p> | ||||
| <pre>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) ; } | ||||
| } ; | ||||
| </pre> | ||||
| <p>The preceding generic function and function object have the following semantics:<br> | ||||
| If both <b>x</b> and <b>y</b> have valid pointees, it compares values via <code>(*x == *y)</code>.<br> | ||||
| If only one has a valid pointee, returns <code>false</code>.<br> | ||||
| If both have invalid pointees, returns <code>true</code>.</p> | ||||
| <a name="less"></a> | ||||
| <p><u>Less-than relation:</u></p> | ||||
| <pre>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) ; } | ||||
| } ; | ||||
| </pre> | ||||
| <p>The preceding generic function and function object have the following semantics:<br> | ||||
| If <b>y</b> has an invalid pointee, returns <code>false</code>.<br> | ||||
| Else, if <b>x</b> has an invalid pointee, returns <code>true</code>.<br> | ||||
| Else, ( <b>x</b> and <b>y</b> have valid pointees), compares values via <code>(*x <  | ||||
| *y).</code></p> | ||||
| <p><br> | ||||
| All these functions and function  | ||||
| objects are is implemented in <a href="../../boost/utility/compare_pointees.hpp">compare_pointees.hpp</a></p> | ||||
| <p>Notice that OptionalPointee does not imply aliasing (and optional<> for instance does not alias); | ||||
| so direct usage of relational operators with the implied aliasing of shallow semantics | ||||
| -as with pointers- should not be used with generic code written for this concept.</p> | ||||
|  | ||||
| <h3>Acknowledgements</h3> | ||||
| <p>Based on the original concept developed by Augustus Saunders. | ||||
|  | ||||
| <br> | ||||
| </p> | ||||
| <HR> | ||||
| <TABLE> | ||||
| <TR valign=top> | ||||
| <TD nowrap>Copyright © 2003</TD><TD> | ||||
| <A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A> | ||||
| </TD></TR></TABLE> | ||||
|  | ||||
| <p>Distributed under the Boost Software License, Version 1.0. See | ||||
| <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p> | ||||
|  | ||||
| </BODY> | ||||
| </HTML> | ||||
							
								
								
									
										94
									
								
								addressof_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								addressof_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| // Copyright (C) 2002 Brad King (brad.king@kitware.com)  | ||||
| //                    Douglas Gregor (gregod@cs.rpi.edu) | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| // For more information, see http://www.boost.org | ||||
|  | ||||
|  | ||||
| #include <boost/utility/addressof.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | ||||
| #pragma warning(push, 3) | ||||
| #endif | ||||
|  | ||||
| #include <iostream> | ||||
|  | ||||
| #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | ||||
| #pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| template<class T> void scalar_test( T * = 0 ) | ||||
| { | ||||
|     T* px = new T(); | ||||
|  | ||||
|     T& x = *px; | ||||
|     BOOST_TEST( boost::addressof(x) == px ); | ||||
|  | ||||
|     const T& cx = *px; | ||||
|     const T* pcx = boost::addressof(cx); | ||||
|     BOOST_TEST( pcx == px ); | ||||
|  | ||||
|     volatile T& vx = *px; | ||||
|     volatile T* pvx = boost::addressof(vx); | ||||
|     BOOST_TEST( pvx == px ); | ||||
|  | ||||
|     const volatile T& cvx = *px; | ||||
|     const volatile T* pcvx = boost::addressof(cvx); | ||||
|     BOOST_TEST( pcvx == px ); | ||||
|  | ||||
|     delete px; | ||||
| } | ||||
|  | ||||
| template<class T> void array_test( T * = 0 ) | ||||
| { | ||||
|     T nrg[3] = {1,2,3}; | ||||
|     T (*pnrg)[3] = &nrg; | ||||
|     BOOST_TEST( boost::addressof(nrg) == pnrg ); | ||||
|  | ||||
|     T const cnrg[3] = {1,2,3}; | ||||
|     T const (*pcnrg)[3] = &cnrg; | ||||
|     BOOST_TEST( boost::addressof(cnrg) == pcnrg ); | ||||
| } | ||||
|  | ||||
| struct addressable | ||||
| { | ||||
|     addressable( int = 0 ) | ||||
|     { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| struct useless_type {}; | ||||
|  | ||||
| class nonaddressable { | ||||
| public: | ||||
|  | ||||
|     nonaddressable( int = 0 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     void dummy(); // Silence GCC warning: all member of class are private | ||||
|  | ||||
| private: | ||||
|  | ||||
|     useless_type operator&() const; | ||||
| }; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     scalar_test<char>(); | ||||
|     scalar_test<int>(); | ||||
|     scalar_test<addressable>(); | ||||
|     scalar_test<nonaddressable>(); | ||||
|  | ||||
|     array_test<char>(); | ||||
|     array_test<int>(); | ||||
|     array_test<addressable>(); | ||||
|     array_test<nonaddressable>(); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										61
									
								
								assert.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								assert.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | ||||
| <html> | ||||
| 	<head> | ||||
| 		<title>Boost: assert.hpp documentation</title> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||||
| 	</head> | ||||
| 	<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> | ||||
| 		<table border="0" width="100%"> | ||||
| 			<tr> | ||||
| 				<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> | ||||
| 				</td> | ||||
| 				<td align="center"> | ||||
| 					<h1>assert.hpp</h1> | ||||
| 				</td> | ||||
| 			</tr> | ||||
| 			<tr> | ||||
| 				<td colspan="2" height="64"> </td> | ||||
| 			</tr> | ||||
| 		</table> | ||||
| 		<p> | ||||
| 			The header <STRONG><boost/assert.hpp></STRONG> defines the macro <b>BOOST_ASSERT</b>,  | ||||
| 			which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG><cassert></STRONG>.  | ||||
| 			The macro is intended to be used in Boost libraries. | ||||
| 		</p> | ||||
| 		<P>By default, <tt>BOOST_ASSERT(expr)</tt> is equivalent to <tt>assert(expr)</tt>.</P> | ||||
| 		<P>When the macro <STRONG>BOOST_DISABLE_ASSERTS</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG> | ||||
| 			is included, <tt>BOOST_ASSERT(expr)</tt> is defined as <tt>((void)0)</tt>. This  | ||||
| 			allows users to selectively disable <STRONG>BOOST_ASSERT</STRONG> without  | ||||
| 			affecting the definition of the standard <STRONG>assert</STRONG>.</P> | ||||
| 		<P>When the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG> | ||||
| 			is included, <tt>BOOST_ASSERT(expr)</tt> evaluates <b>expr</b> and, if the  | ||||
| 			result is false, evaluates the expression</P> | ||||
| 		<P><tt>::boost::assertion_failed(#expr, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,  | ||||
| 				__FILE__, __LINE__)</tt></P> | ||||
| 		<P><STRONG>assertion_failed</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG> | ||||
| 			as</P> | ||||
| 		<pre> | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| void assertion_failed(char const * expr, char const * function, char const * file, long line); | ||||
|  | ||||
| } | ||||
| </pre> | ||||
| 		<p>but it is never defined. The user is expected to supply an appropriate  | ||||
| 			definition.</p> | ||||
| 		<P>As is the case with <STRONG><cassert></STRONG>, <STRONG><boost/assert.hpp></STRONG> | ||||
| 			can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT</STRONG> | ||||
| 			will be redefined each time as specified above.</P> | ||||
| 		<p><STRONG><boost/assert.hpp></STRONG> also defines the macro <STRONG>BOOST_VERIFY</STRONG>.  | ||||
| 			It has exactly the same behavior as <STRONG>BOOST_ASSERT</STRONG>, except that  | ||||
| 			the expression that is passed to <STRONG>BOOST_VERIFY</STRONG> is always  | ||||
| 			evaluated. This is useful when the asserted expression has desirable side  | ||||
| 			effects; it can also help suppress warnings about unused variables when the  | ||||
| 			only use of the variable is inside an assertion.</p> | ||||
| 		<p><br> | ||||
| 			<small>Copyright <20> 2002, 2007 by Peter Dimov. Distributed under the Boost Software  | ||||
| 				License, Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> | ||||
| 				or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> | ||||
| 	</body> | ||||
| </html> | ||||
							
								
								
									
										109
									
								
								assert_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								assert_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| // | ||||
| //  assert_test.cpp - a test for boost/assert.hpp | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| #include <boost/assert.hpp> | ||||
|  | ||||
| void test_default() | ||||
| { | ||||
|     int x = 1; | ||||
|  | ||||
|     BOOST_ASSERT(1); | ||||
|     BOOST_ASSERT(x); | ||||
|     BOOST_ASSERT(x == 1); | ||||
|     BOOST_ASSERT(&x); | ||||
| } | ||||
|  | ||||
| #define BOOST_DISABLE_ASSERTS | ||||
| #include <boost/assert.hpp> | ||||
|  | ||||
| void test_disabled() | ||||
| { | ||||
|     int x = 1; | ||||
|  | ||||
|     BOOST_ASSERT(1); | ||||
|     BOOST_ASSERT(x); | ||||
|     BOOST_ASSERT(x == 1); | ||||
|     BOOST_ASSERT(&x); | ||||
|  | ||||
|     BOOST_ASSERT(0); | ||||
|     BOOST_ASSERT(!x); | ||||
|     BOOST_ASSERT(x == 0); | ||||
|  | ||||
|     void * p = 0; | ||||
|  | ||||
|     BOOST_ASSERT(p); | ||||
|  | ||||
|     // supress warnings | ||||
|     p = &x; | ||||
|     p = &p; | ||||
| } | ||||
|  | ||||
| #undef BOOST_DISABLE_ASSERTS | ||||
|  | ||||
| #define BOOST_ENABLE_ASSERT_HANDLER | ||||
| #include <boost/assert.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <cstdio> | ||||
|  | ||||
| int handler_invoked = 0; | ||||
|  | ||||
| void boost::assertion_failed(char const * expr, char const * function, char const * file, long line) | ||||
| { | ||||
| #if !defined(BOOST_NO_STDC_NAMESPACE) | ||||
|     using std::printf; | ||||
| #endif | ||||
|  | ||||
|     printf("Expression: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", expr, function, file, line); | ||||
|     ++handler_invoked; | ||||
| } | ||||
|  | ||||
| struct X | ||||
| { | ||||
|     static void f() | ||||
|     { | ||||
|         BOOST_ASSERT(0); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| void test_handler() | ||||
| { | ||||
|     int x = 1; | ||||
|  | ||||
|     BOOST_ASSERT(1); | ||||
|     BOOST_ASSERT(x); | ||||
|     BOOST_ASSERT(x == 1); | ||||
|     BOOST_ASSERT(&x); | ||||
|  | ||||
|     BOOST_ASSERT(0); | ||||
|     BOOST_ASSERT(!x); | ||||
|     BOOST_ASSERT(x == 0); | ||||
|  | ||||
|     void * p = 0; | ||||
|  | ||||
|     BOOST_ASSERT(p); | ||||
|  | ||||
|     X::f(); | ||||
|  | ||||
|     BOOST_ASSERT(handler_invoked == 5); | ||||
|     BOOST_TEST(handler_invoked == 5); | ||||
| } | ||||
|  | ||||
| #undef BOOST_ENABLE_ASSERT_HANDLER | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     test_default(); | ||||
|     test_disabled(); | ||||
|     test_handler(); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										371
									
								
								base_from_member.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								base_from_member.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,371 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> | ||||
| <html> | ||||
| <head> | ||||
| <title>Boost: Base-from-Member Idiom Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="white" link="blue" text="black" vlink="purple" alink="red">  | ||||
| <h1><img src="../../boost.png" alt="C++ Boost" align="middle" | ||||
| width="277" height="86">Base-from-Member Idiom</h1> | ||||
|  | ||||
| <p>The class template <code>boost::base_from_member</code> provides | ||||
| a workaround for a class that needs to initialize a base class with a | ||||
| member.  The class template is in <cite><a | ||||
| href="../../boost/utility/base_from_member.hpp">boost/utility/base_from_member.hpp</a></cite> | ||||
| which is included in <i><a href="../../boost/utility.hpp">boost/utility.hpp</a></i>.</p> | ||||
|  | ||||
| <p>There is test/example code in <cite><a | ||||
| href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>.</p> | ||||
|  | ||||
| <h2><a name="contents">Contents</a></h2> | ||||
|  | ||||
| <ul> | ||||
| 	<li><a href="#contents">Contents</a></li> | ||||
| 	<li><a href="#rationale">Rationale</a></li> | ||||
| 	<li><a href="#synopsis">Synopsis</a></li> | ||||
| 	<li><a href="#usage">Usage</a></li> | ||||
| 	<li><a href="#example">Example</a></li> | ||||
| 	<li><a href="#credits">Credits</a> | ||||
| 		<ul> | ||||
| 			<li><a href="#contributors">Contributors</a></li> | ||||
| 		</ul></li> | ||||
| </ul> | ||||
|  | ||||
| <h2><a name="rationale">Rationale</a></h2> | ||||
|  | ||||
| <p>When developing a class, sometimes a base class needs to be | ||||
| initialized with a member of the current class.  As a naïve | ||||
| example:</p> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <streambuf>  <i>// for std::streambuf</i> | ||||
| #include <ostream>    <i>// for std::ostream</i> | ||||
|  | ||||
| class fdoutbuf | ||||
|     : public std::streambuf | ||||
| { | ||||
| public: | ||||
|     explicit fdoutbuf( int fd ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class fdostream | ||||
|     : public std::ostream | ||||
| { | ||||
| protected: | ||||
|     fdoutbuf buf; | ||||
| public: | ||||
|     explicit fdostream( int fd ) | ||||
|         : buf( fd ), std::ostream( &buf ) | ||||
|         {} | ||||
|     //... | ||||
| }; | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>This is undefined because C++'s initialization order mandates that | ||||
| the base class is initialized before the member it uses.  <a | ||||
| href="http://www.moocat.org">R. Samuel Klatchko</a> developed a way | ||||
| around this by using the initialization order in his favor.  Base | ||||
| classes are intialized in order of declaration, so moving the desired | ||||
| member to another base class, that is initialized before the desired | ||||
| base class, can ensure proper initialization.</p> | ||||
|  | ||||
| <p>A custom base class can be made for this idiom:</p> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <streambuf>  <i>// for std::streambuf</i> | ||||
| #include <ostream>    <i>// for std::ostream</i> | ||||
|  | ||||
| class fdoutbuf | ||||
|     : public std::streambuf | ||||
| { | ||||
| public: | ||||
|     explicit fdoutbuf( int fd ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| struct fdostream_pbase | ||||
| { | ||||
|     fdoutbuf sbuffer; | ||||
|  | ||||
|     explicit fdostream_pbase( int fd ) | ||||
|         : sbuffer( fd ) | ||||
|         {} | ||||
| }; | ||||
|  | ||||
| class fdostream | ||||
|     : private fdostream_pbase | ||||
|     , public std::ostream | ||||
| { | ||||
|     typedef fdostream_pbase  pbase_type; | ||||
|     typedef std::ostream     base_type; | ||||
|  | ||||
| public: | ||||
|     explicit fdostream( int fd ) | ||||
|         : pbase_type( fd ), base_type( &sbuffer ) | ||||
|         {} | ||||
|     //... | ||||
| }; | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>Other projects can use similar custom base classes.  The technique | ||||
| is basic enough to make a template, with a sample template class in | ||||
| this library.  The main template parameter is the type of the enclosed | ||||
| member.  The template class has several (explicit) constructor member | ||||
| templates, which implicitly type the constructor arguments and pass them | ||||
| to the member.  The template class uses implicit copy construction and | ||||
| assignment, cancelling them if the enclosed member is non-copyable.</p> | ||||
|  | ||||
| <p>Manually coding a base class may be better if the construction | ||||
| and/or copying needs are too complex for the supplied template class, | ||||
| or if the compiler is not advanced enough to use it.</p> | ||||
|  | ||||
| <p>Since base classes are unnamed, a class cannot have multiple (direct) | ||||
| base classes of the same type.  The supplied template class has an | ||||
| extra template parameter, an integer, that exists solely to provide type | ||||
| differentiation.  This parameter has a default value so a single use of a | ||||
| particular member type does not need to concern itself with the integer.</p> | ||||
|  | ||||
| <h2><a name="synopsis">Synopsis</a></h2> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY | ||||
| #define BOOST_BASE_FROM_MEMBER_MAX_ARITY  10 | ||||
| #endif | ||||
|  | ||||
| template < typename MemberType, int UniqueID = 0 > | ||||
| class boost::base_from_member | ||||
| { | ||||
| protected: | ||||
|     MemberType  member; | ||||
|  | ||||
|     base_from_member(); | ||||
|  | ||||
|     template< typename T1 > | ||||
|     explicit  base_from_member( T1 x1 ); | ||||
|  | ||||
|     template< typename T1, typename T2 > | ||||
|     base_from_member( T1 x1, T2 x2 ); | ||||
|  | ||||
|     //... | ||||
|  | ||||
|     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 ); | ||||
| }; | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>The class template has a first template parameter | ||||
| <var>MemberType</var> representing the type of the based-member. | ||||
| It has a last template parameter <var>UniqueID</var>, that is an | ||||
| <code>int</code>, to differentiate between multiple base classes that use | ||||
| the same based-member type.  The last template parameter has a default | ||||
| value of zero if it is omitted.  The class template has a protected | ||||
| data member called <var>member</var> that the derived class can use | ||||
| for later base classes (or itself).</p> | ||||
|  | ||||
| <p>There is a default constructor and several constructor member | ||||
| templates.  These constructor templates can take as many arguments | ||||
| (currently up to ten) as possible and pass them to a constructor of | ||||
| the data member.  Since C++ does not allow any way to explicitly state | ||||
| the template parameters of a templated constructor, make sure that | ||||
| the arguments are already close as possible to the actual type used in | ||||
| the data member's desired constructor.</p> | ||||
|  | ||||
| <p>The <var>BOOST_BASE_FROM_MEMBER_MAX_ARITY</var> macro constant specifies | ||||
| the maximum argument length for the constructor templates.  The constant | ||||
| may be overridden if more (or less) argument configurations are needed.  The | ||||
| constant may be read for code that is expandable like the class template and | ||||
| needs to maintain the same maximum size.  (Example code would be a class that | ||||
| uses this class template as a base class for a member with a flexible set of | ||||
| constructors.)</p> | ||||
|  | ||||
| <h2><a name="usage">Usage</a></h2> | ||||
|  | ||||
| <p>With the starting example, the <code>fdoutbuf</code> sub-object needs | ||||
| to be encapsulated in a base class that is inheirited before | ||||
| <code>std::ostream</code>.</p> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <boost/utility/base_from_member.hpp> | ||||
|  | ||||
| #include <streambuf>  <i>// for std::streambuf</i> | ||||
| #include <ostream>    <i>// for std::ostream</i> | ||||
|  | ||||
| class fdoutbuf | ||||
|     : public std::streambuf | ||||
| { | ||||
| public: | ||||
|     explicit fdoutbuf( int fd ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class fdostream | ||||
|     : private boost::base_from_member<fdoutbuf> | ||||
|     , public std::ostream | ||||
| { | ||||
|     // Helper typedef's | ||||
|     typedef boost::base_from_member<fdoutbuf>  pbase_type; | ||||
|     typedef std::ostream                        base_type; | ||||
|  | ||||
| public: | ||||
|     explicit fdostream( int fd ) | ||||
|         : pbase_type( fd ), base_type( &member ) | ||||
|         {} | ||||
|     //... | ||||
| }; | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>The base-from-member idiom is an implementation detail, so it | ||||
| should not be visible to the clients (or any derived classes) of | ||||
| <code>fdostream</code>.  Due to the initialization order, the | ||||
| <code>fdoutbuf</code> sub-object will get initialized before the | ||||
| <code>std::ostream</code> sub-object does, making the former | ||||
| sub-object safe to use in the latter sub-object's construction.  Since the | ||||
| <code>fdoutbuf</code> sub-object of the final type is the only sub-object | ||||
| with the name "member," that name can be used | ||||
| unqualified within the final class.</p> | ||||
|  | ||||
| <h2><a name="example">Example</a></h2> | ||||
|  | ||||
| <p>The base-from-member class templates should commonly involve | ||||
| only one base-from-member sub-object, usually for attaching a | ||||
| stream-buffer to an I/O stream.  The next example demonstrates how | ||||
| to use multiple base-from-member sub-objects and the resulting | ||||
| qualification issues.</p> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <boost/utility/base_from_member.hpp> | ||||
|  | ||||
| #include <cstddef>  <i>// for NULL</i> | ||||
|  | ||||
| struct an_int | ||||
| { | ||||
|     int  y; | ||||
|  | ||||
|     an_int( float yf ); | ||||
| }; | ||||
|  | ||||
| class switcher | ||||
| { | ||||
| public: | ||||
|     switcher(); | ||||
|     switcher( double, int * ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class flow_regulator | ||||
| { | ||||
| public: | ||||
|     flow_regulator( switcher &, switcher & ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| template < unsigned Size > | ||||
| class fan | ||||
| { | ||||
| public: | ||||
|     explicit fan( switcher ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class system | ||||
|     : private boost::base_from_member<an_int> | ||||
|     , private boost::base_from_member<switcher> | ||||
|     , private boost::base_from_member<switcher, 1> | ||||
|     , private boost::base_from_member<switcher, 2> | ||||
|     , protected flow_regulator | ||||
|     , public fan<6> | ||||
| { | ||||
|     // Helper typedef's | ||||
|     typedef boost::base_from_member<an_int>       pbase0_type; | ||||
|     typedef boost::base_from_member<switcher>     pbase1_type; | ||||
|     typedef boost::base_from_member<switcher, 1>  pbase2_type; | ||||
|     typedef boost::base_from_member<switcher, 2>  pbase3_type; | ||||
|  | ||||
|     typedef flow_regulator  base1_type; | ||||
|     typedef fan<6>          base2_type; | ||||
|  | ||||
| public: | ||||
|     system( double x ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| system::system( double x ) | ||||
|     : pbase0_type( 0.2 ) | ||||
|     , pbase1_type() | ||||
|     , pbase2_type( -16, &this->pbase0_type::member ) | ||||
|     , pbase3_type( x, static_cast<int *>(NULL) ) | ||||
|     , base1_type( pbase3_type::member, pbase1_type::member ) | ||||
|     , base2_type( pbase2_type::member ) | ||||
| { | ||||
|     //... | ||||
| } | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>The final class has multiple sub-objects with the name | ||||
| "member," so any use of that name needs qualification by | ||||
| a name of the appropriate base type.  (Using <code>typedef</code>s | ||||
| ease mentioning the base types.)  However, the fix introduces a new | ||||
| problem when a pointer is needed.  Using the address operator with | ||||
| a sub-object qualified with its class's name results in a pointer-to-member | ||||
| (here, having a type of <code>an_int boost::base_from_member<an_int, | ||||
| 0> :: *</code>) instead of a pointer to the member (having a type of | ||||
| <code>an_int *</code>).  The new problem is fixed by qualifying the | ||||
| sub-object with "<code>this-></code>," and is needed just | ||||
| for pointers, and not for references or values.</p> | ||||
|  | ||||
| <p>There are some argument conversions in the initialization.  The | ||||
| constructor argument for <code>pbase0_type</code> is converted from | ||||
| <code>double</code> to <code>float</code>.  The first constructor | ||||
| argument for <code>pbase2_type</code> is converted from <code>int</code> | ||||
| to <code>double</code>.  The second constructor argument for | ||||
| <code>pbase3_type</code> is a special case of necessary conversion; all | ||||
| forms of the null-pointer literal in C++ also look like compile-time | ||||
| integral expressions, so C++ always interprets such code as an integer | ||||
| when it has overloads that can take either an integer or a pointer.  The | ||||
| last conversion is necessary for the compiler to call a constructor form | ||||
| with the exact pointer type used in <code>switcher</code>'s constructor.</p> | ||||
|  | ||||
| <h2><a name="credits">Credits</a></h2> | ||||
|  | ||||
| <h3><a name="contributors">Contributors</a></h3> | ||||
|  | ||||
| <dl> | ||||
| 	<dt><a href="http://www.boost.org/people/ed_brey.htm">Ed Brey</a> | ||||
| 	<dd>Suggested some interface changes. | ||||
|  | ||||
| 	<dt><a href="http://www.moocat.org">R. Samuel Klatchko</a> (<a | ||||
| 	href="mailto:rsk@moocat.org">rsk@moocat.org</a>, <a | ||||
| 	href="mailto:rsk@brightmail.com">rsk@brightmail.com</a>) | ||||
| 	<dd>Invented the idiom of how to use a class member for initializing | ||||
| 		a base class. | ||||
|  | ||||
| 	<dt><a href="http://www.boost.org/people/dietmar_kuehl.htm">Dietmar Kuehl</a> | ||||
| 	<dd>Popularized the base-from-member idiom in his | ||||
| 		<a href="http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/">IOStream | ||||
| 		example classes</a>. | ||||
|  | ||||
| 	<dt>Jonathan Turkanis | ||||
| 	<dd>Supplied an implementation of generating the constructor templates that | ||||
| 		can be controlled and automated with macros.  The implementation uses | ||||
| 		the <a href="../preprocessor/index.html">Preprocessor library</a>. | ||||
|  | ||||
| 	<dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a> | ||||
| 	<dd>Started the library.  Contributed the test file <cite><a | ||||
| 		href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>. | ||||
| </dl> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <p>Revised: 28 August 2004</p> | ||||
|  | ||||
| <p>Copyright 2001, 2003, 2004 Daryle Walker.  Use, modification, and distribution | ||||
| are subject to the Boost Software License, Version 1.0.  (See accompanying | ||||
| file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a | ||||
| href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p> | ||||
|  | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										595
									
								
								base_from_member_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										595
									
								
								base_from_member_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,595 @@ | ||||
| //  Boost test program for base-from-member class templates  -----------------// | ||||
|  | ||||
| //  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. | ||||
|  | ||||
| //  Revision History | ||||
| //  14 Jun 2003  Adjusted code for Boost.Test changes (Daryle Walker) | ||||
| //  29 Aug 2001  Initial Version (Daryle Walker) | ||||
|  | ||||
| #include <boost/test/minimal.hpp>  // for BOOST_CHECK, main | ||||
|  | ||||
| #include <boost/config.hpp>       // for BOOST_NO_MEMBER_TEMPLATES | ||||
| #include <boost/cstdlib.hpp>      // for boost::exit_success | ||||
| #include <boost/noncopyable.hpp>  // for boost::noncopyable | ||||
|  | ||||
| #include <boost/utility/base_from_member.hpp>  // for boost::base_from_member | ||||
|  | ||||
| #include <functional>  // for std::binary_function, std::less | ||||
| #include <iostream>    // for std::cout (std::ostream, std::endl indirectly) | ||||
| #include <set>         // for std::set | ||||
| #include <typeinfo>    // for std::type_info | ||||
| #include <utility>     // for std::pair, std::make_pair | ||||
| #include <vector>      // for std::vector | ||||
|  | ||||
|  | ||||
| // Control if extra information is printed | ||||
| #ifndef CONTROL_EXTRA_PRINTING | ||||
| #define CONTROL_EXTRA_PRINTING  1 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| // A (sub)object can be identified by its memory location and its type. | ||||
| // Both are needed since an object can start at the same place as its | ||||
| // first base class subobject and/or contained subobject. | ||||
| typedef std::pair< void *, std::type_info const * >  object_id; | ||||
|  | ||||
| // Object IDs need to be printed | ||||
| std::ostream &  operator <<( std::ostream &os, object_id const &oi ); | ||||
|  | ||||
| // A way to generate an object ID | ||||
| template < typename T > | ||||
|   object_id  identify( T &obj ); | ||||
|  | ||||
| // A custom comparison type is needed | ||||
| struct object_id_compare | ||||
|     : std::binary_function<object_id, object_id, bool> | ||||
| { | ||||
|     bool  operator ()( object_id const &a, object_id const &b ) const; | ||||
|  | ||||
| };  // object_id_compare | ||||
|  | ||||
| // A singleton of this type coordinates the acknowledgements | ||||
| // of objects being created and used. | ||||
| class object_registrar | ||||
|     : private boost::noncopyable | ||||
| { | ||||
| public: | ||||
|  | ||||
|     #ifndef BOOST_NO_MEMBER_TEMPLATES | ||||
|     template < typename T > | ||||
|         void  register_object( T &obj ) | ||||
|             { this->register_object_imp( identify(obj) ); } | ||||
|     template < typename T, typename U > | ||||
|         void  register_use( T &owner, U &owned ) | ||||
|             { this->register_use_imp( identify(owner), identify(owned) ); } | ||||
|     template < typename T, typename U > | ||||
|         void  unregister_use( T &owner, U &owned ) | ||||
|             { this->unregister_use_imp( identify(owner), identify(owned) ); } | ||||
|     template < typename T > | ||||
|         void  unregister_object( T &obj ) | ||||
|             { this->unregister_object_imp( identify(obj) ); } | ||||
|     #endif | ||||
|  | ||||
|     void  register_object_imp( object_id obj ); | ||||
|     void  register_use_imp( object_id owner, object_id owned ); | ||||
|     void  unregister_use_imp( object_id owner, object_id owned ); | ||||
|     void  unregister_object_imp( object_id obj ); | ||||
|  | ||||
|     typedef std::set<object_id, object_id_compare>  set_type; | ||||
|  | ||||
|     typedef std::vector<object_id>  error_record_type; | ||||
|     typedef std::vector< std::pair<object_id, object_id> >  error_pair_type; | ||||
|  | ||||
|     set_type  db_; | ||||
|  | ||||
|     error_pair_type    defrauders_in_, defrauders_out_; | ||||
|     error_record_type  overeager_, overkilled_; | ||||
|  | ||||
| };  // object_registrar | ||||
|  | ||||
| // A sample type to be used by containing types | ||||
| class base_or_member | ||||
| { | ||||
| public: | ||||
|     explicit  base_or_member( int x = 1, double y = -0.25 ); | ||||
|              ~base_or_member(); | ||||
|  | ||||
| };  // base_or_member | ||||
|  | ||||
| // A sample type that uses base_or_member, used | ||||
| // as a base for the main demonstration classes | ||||
| class base_class | ||||
| { | ||||
| public: | ||||
|     explicit  base_class( base_or_member &x, base_or_member *y = 0, | ||||
|      base_or_member *z = 0 ); | ||||
|  | ||||
|     ~base_class(); | ||||
|  | ||||
| private: | ||||
|     base_or_member  *x_, *y_, *z_; | ||||
|  | ||||
| };  // base_class | ||||
|  | ||||
| // This bad class demonstrates the direct method of a base class needing | ||||
| // to be initialized by a member.  This is improper since the member | ||||
| // isn't initialized until after the base class. | ||||
| class bad_class | ||||
|     : public base_class | ||||
| { | ||||
| public: | ||||
|      bad_class(); | ||||
|     ~bad_class(); | ||||
|  | ||||
| private: | ||||
|     base_or_member  x_; | ||||
|  | ||||
| };  // bad_class | ||||
|  | ||||
| // The first good class demonstrates the correct way to initialize a | ||||
| // base class with a member.  The member is changed to another base | ||||
| // class, one that is initialized before the base that needs it. | ||||
| class good_class_1 | ||||
|     : private boost::base_from_member<base_or_member> | ||||
|     , public base_class | ||||
| { | ||||
|     typedef boost::base_from_member<base_or_member>  pbase_type; | ||||
|     typedef base_class                                base_type; | ||||
|  | ||||
| public: | ||||
|      good_class_1(); | ||||
|     ~good_class_1(); | ||||
|  | ||||
| };  // good_class_1 | ||||
|  | ||||
| // The second good class also demonstrates the correct way to initialize | ||||
| // base classes with other subobjects.  This class uses the other helpers | ||||
| // in the library, and shows the technique of using two base subobjects | ||||
| // of the "same" type. | ||||
| class good_class_2 | ||||
|     : private boost::base_from_member<base_or_member, 0> | ||||
|     , private boost::base_from_member<base_or_member, 1> | ||||
|     , private boost::base_from_member<base_or_member, 2> | ||||
|     , public base_class | ||||
| { | ||||
|     typedef boost::base_from_member<base_or_member, 0>  pbase_type0; | ||||
|     typedef boost::base_from_member<base_or_member, 1>  pbase_type1; | ||||
|     typedef boost::base_from_member<base_or_member, 2>  pbase_type2; | ||||
|     typedef base_class                                   base_type; | ||||
|  | ||||
| public: | ||||
|      good_class_2(); | ||||
|     ~good_class_2(); | ||||
|  | ||||
| };  // good_class_2 | ||||
|  | ||||
| // Declare/define the single object registrar | ||||
| object_registrar  obj_reg; | ||||
|  | ||||
|  | ||||
| // Main functionality | ||||
| int | ||||
| test_main( int , char * [] ) | ||||
| { | ||||
|     BOOST_CHECK( obj_reg.db_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.defrauders_in_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.defrauders_out_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.overeager_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.overkilled_.empty() ); | ||||
|  | ||||
|     // Make a separate block to examine pre- and post-effects | ||||
|     { | ||||
|         using std::cout; | ||||
|         using std::endl; | ||||
|  | ||||
|         bad_class  bc; | ||||
|         BOOST_CHECK( obj_reg.db_.size() == 3 ); | ||||
|         BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 ); | ||||
|  | ||||
|         good_class_1  gc1; | ||||
|         BOOST_CHECK( obj_reg.db_.size() == 6 ); | ||||
|         BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 ); | ||||
|  | ||||
|         good_class_2  gc2; | ||||
|         BOOST_CHECK( obj_reg.db_.size() == 11 ); | ||||
|         BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 ); | ||||
|  | ||||
|         BOOST_CHECK( obj_reg.defrauders_out_.empty() ); | ||||
|         BOOST_CHECK( obj_reg.overeager_.empty() ); | ||||
|         BOOST_CHECK( obj_reg.overkilled_.empty() ); | ||||
|  | ||||
|         // Getting the addresses of the objects ensure | ||||
|         // that they're used, and not optimized away. | ||||
|         cout << "Object 'bc' is at " << &bc << '.' << endl; | ||||
|         cout << "Object 'gc1' is at " << &gc1 << '.' << endl; | ||||
|         cout << "Object 'gc2' is at " << &gc2 << '.' << endl; | ||||
|     } | ||||
|  | ||||
|     BOOST_CHECK( obj_reg.db_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 ); | ||||
|     BOOST_CHECK( obj_reg.defrauders_out_.size() == 1 ); | ||||
|     BOOST_CHECK( obj_reg.overeager_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.overkilled_.empty() ); | ||||
|  | ||||
|     return boost::exit_success; | ||||
| } | ||||
|  | ||||
|  | ||||
| // Print an object's ID | ||||
| std::ostream & | ||||
| operator << | ||||
| ( | ||||
|     std::ostream &     os, | ||||
|     object_id const &  oi | ||||
| ) | ||||
| { | ||||
|     // I had an std::ostringstream to help, but I did not need it since | ||||
|     // the program never screws around with formatting.  Worse, using | ||||
|     // std::ostringstream is an issue with some compilers. | ||||
|  | ||||
|     return os << '[' << ( oi.second ? oi.second->name() : "NOTHING" ) | ||||
|      << " at " << oi.first << ']'; | ||||
| } | ||||
|  | ||||
| // Get an object ID given an object | ||||
| template < typename T > | ||||
| inline | ||||
| object_id | ||||
| identify | ||||
| ( | ||||
|     T &  obj | ||||
| ) | ||||
| { | ||||
|     return std::make_pair( static_cast<void *>(&obj), &(typeid( obj )) ); | ||||
| } | ||||
|  | ||||
| // Compare two object IDs | ||||
| bool | ||||
| object_id_compare::operator () | ||||
| ( | ||||
|     object_id const &  a, | ||||
|     object_id const &  b | ||||
| ) const | ||||
| { | ||||
|     std::less<void *>  vp_cmp; | ||||
|     if ( vp_cmp(a.first, b.first) ) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
|     else if ( vp_cmp(b.first, a.first) ) | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // object pointers are equal, compare the types | ||||
|         if ( a.second == b.second ) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
|         else if ( !a.second ) | ||||
|         { | ||||
|             return true;   // NULL preceeds anything else | ||||
|         } | ||||
|         else if ( !b.second ) | ||||
|         { | ||||
|             return false;  // NULL preceeds anything else | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return a.second->before( *b.second ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Let an object register its existence | ||||
| void | ||||
| object_registrar::register_object_imp | ||||
| ( | ||||
|     object_id  obj | ||||
| ) | ||||
| { | ||||
|     if ( db_.count(obj) <= 0 ) | ||||
|     { | ||||
|         db_.insert( obj ); | ||||
|  | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << "Registered " << obj << '.' << std::endl; | ||||
|         #endif | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         overeager_.push_back( obj ); | ||||
|  | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << "Attempted to register a non-existant " << obj | ||||
|          << '.' << std::endl; | ||||
|         #endif | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Let an object register its use of another object | ||||
| void | ||||
| object_registrar::register_use_imp | ||||
| ( | ||||
|     object_id  owner, | ||||
|     object_id  owned | ||||
| ) | ||||
| { | ||||
|     if ( db_.count(owned) > 0 ) | ||||
|     { | ||||
|         // We don't care to record usage registrations | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         defrauders_in_.push_back( std::make_pair(owner, owned) ); | ||||
|  | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << "Attempted to own a non-existant " << owned | ||||
|          << " by " << owner << '.' << std::endl; | ||||
|         #endif | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Let an object un-register its use of another object | ||||
| void | ||||
| object_registrar::unregister_use_imp | ||||
| ( | ||||
|     object_id  owner, | ||||
|     object_id  owned | ||||
| ) | ||||
| { | ||||
|     if ( db_.count(owned) > 0 ) | ||||
|     { | ||||
|         // We don't care to record usage un-registrations | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         defrauders_out_.push_back( std::make_pair(owner, owned) ); | ||||
|  | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << "Attempted to disown a non-existant " << owned | ||||
|          << " by " << owner << '.' << std::endl; | ||||
|         #endif | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Let an object un-register its existence | ||||
| void | ||||
| object_registrar::unregister_object_imp | ||||
| ( | ||||
|     object_id  obj | ||||
| ) | ||||
| { | ||||
|     set_type::iterator const  i = db_.find( obj ); | ||||
|  | ||||
|     if ( i != db_.end() ) | ||||
|     { | ||||
|         db_.erase( i ); | ||||
|  | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << "Unregistered " << obj << '.' << std::endl; | ||||
|         #endif | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         overkilled_.push_back( obj ); | ||||
|  | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << "Attempted to unregister a non-existant " << obj | ||||
|          << '.' << std::endl; | ||||
|         #endif | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Macros to abstract the registration of objects | ||||
| #ifndef BOOST_NO_MEMBER_TEMPLATES | ||||
| #define PRIVATE_REGISTER_BIRTH(o)     obj_reg.register_object( (o) ) | ||||
| #define PRIVATE_REGISTER_DEATH(o)     obj_reg.unregister_object( (o) ) | ||||
| #define PRIVATE_REGISTER_USE(o, w)    obj_reg.register_use( (o), (w) ) | ||||
| #define PRIVATE_UNREGISTER_USE(o, w)  obj_reg.unregister_use( (o), (w) ) | ||||
| #else | ||||
| #define PRIVATE_REGISTER_BIRTH(o)     obj_reg.register_object_imp( \ | ||||
|  identify((o)) ) | ||||
| #define PRIVATE_REGISTER_DEATH(o)     obj_reg.unregister_object_imp( \ | ||||
|  identify((o)) ) | ||||
| #define PRIVATE_REGISTER_USE(o, w)    obj_reg.register_use_imp( identify((o)), \ | ||||
|  identify((w)) ) | ||||
| #define PRIVATE_UNREGISTER_USE(o, w)  obj_reg.unregister_use_imp( \ | ||||
|  identify((o)), identify((w)) ) | ||||
| #endif | ||||
|  | ||||
| // Create a base_or_member, with arguments to simulate member initializations | ||||
| base_or_member::base_or_member | ||||
| ( | ||||
|     int     x,  // = 1 | ||||
|     double  y   // = -0.25 | ||||
| ) | ||||
| { | ||||
|     PRIVATE_REGISTER_BIRTH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy x-factor is " << x << " and my y-factor is " << y | ||||
|      << '.' << std::endl; | ||||
|     #endif | ||||
| } | ||||
|  | ||||
| // Destroy a base_or_member | ||||
| inline | ||||
| base_or_member::~base_or_member | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     PRIVATE_REGISTER_DEATH( *this ); | ||||
| } | ||||
|  | ||||
| // Create a base_class, registering any objects used | ||||
| base_class::base_class | ||||
| ( | ||||
|     base_or_member &  x, | ||||
|     base_or_member *  y,  // = 0 | ||||
|     base_or_member *  z   // = 0 | ||||
| ) | ||||
|     : x_( &x ), y_( y ), z_( z ) | ||||
| { | ||||
|     PRIVATE_REGISTER_BIRTH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy x-factor is " << x_; | ||||
|     #endif | ||||
|  | ||||
|     PRIVATE_REGISTER_USE( *this, *x_ ); | ||||
|  | ||||
|     if ( y_ ) | ||||
|     { | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << ", my y-factor is " << y_; | ||||
|         #endif | ||||
|  | ||||
|         PRIVATE_REGISTER_USE( *this, *y_ ); | ||||
|     } | ||||
|  | ||||
|     if ( z_ ) | ||||
|     { | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << ", my z-factor is " << z_; | ||||
|         #endif | ||||
|  | ||||
|         PRIVATE_REGISTER_USE( *this, *z_ ); | ||||
|     } | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << '.' << std::endl; | ||||
|     #endif | ||||
| } | ||||
|  | ||||
| // Destroy a base_class, unregistering the objects it uses | ||||
| base_class::~base_class | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     PRIVATE_REGISTER_DEATH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy x-factor was " << x_; | ||||
|     #endif | ||||
|  | ||||
|     PRIVATE_UNREGISTER_USE( *this, *x_ ); | ||||
|  | ||||
|     if ( y_ ) | ||||
|     { | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << ", my y-factor was " << y_; | ||||
|         #endif | ||||
|  | ||||
|         PRIVATE_UNREGISTER_USE( *this, *y_ ); | ||||
|     } | ||||
|  | ||||
|     if ( z_ ) | ||||
|     { | ||||
|         #if CONTROL_EXTRA_PRINTING | ||||
|         std::cout << ", my z-factor was " << z_; | ||||
|         #endif | ||||
|  | ||||
|         PRIVATE_UNREGISTER_USE( *this, *z_ ); | ||||
|     } | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << '.' << std::endl; | ||||
|     #endif | ||||
| } | ||||
|  | ||||
| // Create a bad_class, noting the improper construction order | ||||
| bad_class::bad_class | ||||
| ( | ||||
| ) | ||||
|     : x_( -7, 16.75 ), base_class( x_ )  // this order doesn't matter | ||||
| { | ||||
|     PRIVATE_REGISTER_BIRTH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy factor is at " << &x_ | ||||
|      << " and my base is at " << static_cast<base_class *>(this) << '.' | ||||
|      << std::endl; | ||||
|     #endif | ||||
| } | ||||
|  | ||||
| // Destroy a bad_class, noting the improper destruction order | ||||
| bad_class::~bad_class | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     PRIVATE_REGISTER_DEATH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy factor was at " << &x_ | ||||
|      << " and my base was at " << static_cast<base_class *>(this) | ||||
|      << '.' << std::endl; | ||||
|     #endif | ||||
| } | ||||
|  | ||||
| // Create a good_class_1, noting the proper construction order | ||||
| good_class_1::good_class_1 | ||||
| ( | ||||
| ) | ||||
|     : pbase_type( 8 ), base_type( member ) | ||||
| { | ||||
|     PRIVATE_REGISTER_BIRTH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy factor is at " << &member | ||||
|      << " and my base is at " << static_cast<base_class *>(this) << '.' | ||||
|      << std::endl; | ||||
|     #endif | ||||
| } | ||||
|  | ||||
| // Destroy a good_class_1, noting the proper destruction order | ||||
| good_class_1::~good_class_1 | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     PRIVATE_REGISTER_DEATH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy factor was at " << &member | ||||
|      << " and my base was at " << static_cast<base_class *>(this) | ||||
|      << '.' << std::endl; | ||||
|     #endif | ||||
| } | ||||
|  | ||||
| // Create a good_class_2, noting the proper construction order | ||||
| good_class_2::good_class_2 | ||||
| ( | ||||
| ) | ||||
|     : pbase_type0(), pbase_type1(-16, 0.125), pbase_type2(2, -3) | ||||
|     , base_type( pbase_type1::member, &this->pbase_type0::member, | ||||
|        &this->pbase_type2::member ) | ||||
| { | ||||
|     PRIVATE_REGISTER_BIRTH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy factors are at " << &this->pbase_type0::member | ||||
|      << ", " << &this->pbase_type1::member << ", " | ||||
|      << &this->pbase_type2::member << ", and my base is at " | ||||
|      << static_cast<base_class *>(this) << '.' << std::endl; | ||||
|     #endif | ||||
| } | ||||
|  | ||||
| // Destroy a good_class_2, noting the proper destruction order | ||||
| good_class_2::~good_class_2 | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     PRIVATE_REGISTER_DEATH( *this ); | ||||
|  | ||||
|     #if CONTROL_EXTRA_PRINTING | ||||
|     std::cout << "\tMy factors were at " << &this->pbase_type0::member | ||||
|      << ", " << &this->pbase_type1::member << ", " | ||||
|      << &this->pbase_type2::member << ", and my base was at " | ||||
|      << static_cast<base_class *>(this) << '.' << std::endl; | ||||
|     #endif | ||||
| } | ||||
							
								
								
									
										258
									
								
								binary_search_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								binary_search_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,258 @@ | ||||
| // (C) Copyright David Abrahams 2000. | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <memory> | ||||
| #include <climits> | ||||
| #include <iostream> | ||||
| #include <cassert> | ||||
| #include <stdlib.h> // for rand(). Would use cstdlib but VC6.4 doesn't put it in std:: | ||||
| #include <list> | ||||
| #include <algorithm> | ||||
| #include <boost/detail/binary_search.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <cstddef> | ||||
|  | ||||
| #if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) | ||||
| # define USE_SSTREAM | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_SSTREAM | ||||
| # include <sstream> | ||||
| #else | ||||
| # include <strstream> | ||||
| #endif | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| // In order to get ADL to find the comparison operators defined below, they have | ||||
| struct mystring : std::string | ||||
| { | ||||
|     typedef std::string base; | ||||
|      | ||||
|     mystring(std::string const& x) | ||||
|         : base(x) {} | ||||
| }; | ||||
|  | ||||
| typedef std::vector<mystring> string_vector; | ||||
|  | ||||
| const std::size_t sequence_length = 1000; | ||||
|  | ||||
| unsigned random_number() | ||||
| { | ||||
|     return static_cast<unsigned>(::rand()) % sequence_length; | ||||
| } | ||||
|  | ||||
| # ifndef USE_SSTREAM | ||||
| class unfreezer { | ||||
|  public: | ||||
|     unfreezer(std::ostrstream& s) : m_stream(s) {} | ||||
|     ~unfreezer() { m_stream.freeze(false); } | ||||
|  private: | ||||
|     std::ostrstream& m_stream; | ||||
| }; | ||||
| # endif | ||||
|  | ||||
| template <class T> | ||||
| void push_back_random_number_string(T& seq) | ||||
| { | ||||
|     unsigned value = random_number(); | ||||
| # if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) | ||||
|     std::ostringstream s; | ||||
|     s << value; | ||||
|     seq.push_back(s.str()); | ||||
| # else | ||||
|     std::ostrstream s; | ||||
|     auto unfreezer unfreeze(s); | ||||
|     s << value << char(0); | ||||
|     seq.push_back(std::string(s.str())); | ||||
| # endif | ||||
| } | ||||
|  | ||||
| inline unsigned to_int(unsigned x) { return x; } | ||||
| inline unsigned to_int(const std::string& x) { return atoi(x.c_str()); } | ||||
|  | ||||
| struct cmp | ||||
| { | ||||
|     template <class A1, class A2> | ||||
|     inline bool operator()(const A1& a1, const A2& a2) const | ||||
|     { | ||||
|         return to_int(a1) < to_int(a2); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| inline bool operator<(const mystring& x, const unsigned y) | ||||
| { | ||||
|     return to_int(x) < y; | ||||
| } | ||||
|  | ||||
| inline bool operator<(const unsigned y, const mystring& x) | ||||
| { | ||||
|     return y < to_int(x); | ||||
| } | ||||
|  | ||||
| template <class T> | ||||
| void sort_by_value(T& x); | ||||
|  | ||||
| template <class T> | ||||
| void sort_by_value_(T& v, long) | ||||
| { | ||||
|     std::sort(v.begin(), v.end(), cmp()); | ||||
| } | ||||
|  | ||||
| template <class T> | ||||
| void random_sorted_sequence(T& seq) | ||||
| { | ||||
|     seq.clear(); | ||||
|     for (std::size_t i = 0; i < sequence_length; ++i) | ||||
|     { | ||||
|         push_back_random_number_string(seq); | ||||
|     } | ||||
|     sort_by_value(seq); | ||||
| } | ||||
|  | ||||
| template <class T, class A> | ||||
| void sort_by_value_(std::list<T,A>& l, int) | ||||
| { | ||||
| # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) && !defined(__SGI_STL_PORT) | ||||
| // VC6's standard lib doesn't have a template member function for list::sort() | ||||
|     std::vector<T> seq; | ||||
|     seq.reserve(sequence_length); | ||||
|     std::copy(l.begin(), l.end(), std::back_inserter(seq)); | ||||
|     sort_by_value(seq); | ||||
|     std::copy(seq.begin(), seq.end(), l.begin()); | ||||
| # else | ||||
|     l.sort(cmp()); | ||||
| # endif | ||||
| } | ||||
|  | ||||
| template <class T> | ||||
| void sort_by_value(T& x) | ||||
| { | ||||
|     (sort_by_value_)(x, 1); | ||||
| } | ||||
|  | ||||
| // A way to select the comparisons with/without a Compare parameter for testing. | ||||
| template <class Compare> struct searches | ||||
| { | ||||
|     template <class Iterator, class Key> | ||||
|     static Iterator lower_bound(Iterator start, Iterator finish, Key key, Compare cmp) | ||||
|         { return boost::detail::lower_bound(start, finish, key, cmp); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static Iterator upper_bound(Iterator start, Iterator finish, Key key, Compare cmp) | ||||
|         { return boost::detail::upper_bound(start, finish, key, cmp); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, Compare cmp) | ||||
|         { return boost::detail::equal_range(start, finish, key, cmp); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static bool binary_search(Iterator start, Iterator finish, Key key, Compare cmp) | ||||
|         { return boost::detail::binary_search(start, finish, key, cmp); } | ||||
| }; | ||||
|  | ||||
| struct no_compare {}; | ||||
|  | ||||
| template <> struct searches<no_compare> | ||||
| { | ||||
|     template <class Iterator, class Key> | ||||
|     static Iterator lower_bound(Iterator start, Iterator finish, Key key, no_compare) | ||||
|         { return boost::detail::lower_bound(start, finish, key); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static Iterator upper_bound(Iterator start, Iterator finish, Key key, no_compare) | ||||
|         { return boost::detail::upper_bound(start, finish, key); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, no_compare) | ||||
|         { return boost::detail::equal_range(start, finish, key); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static bool binary_search(Iterator start, Iterator finish, Key key, no_compare) | ||||
|         { return boost::detail::binary_search(start, finish, key); } | ||||
| }; | ||||
|  | ||||
| template <class Sequence, class Compare> | ||||
| void test_loop(Sequence& x, Compare cmp, unsigned long test_count) | ||||
| { | ||||
|     typedef typename Sequence::const_iterator const_iterator; | ||||
|      | ||||
|     for (unsigned long i = 0; i < test_count; ++i) | ||||
|     { | ||||
|         random_sorted_sequence(x); | ||||
|         const const_iterator start = x.begin(); | ||||
|         const const_iterator finish = x.end(); | ||||
|          | ||||
|         unsigned key = random_number(); | ||||
|         const const_iterator l = searches<Compare>::lower_bound(start, finish, key, cmp); | ||||
|         const const_iterator u = searches<Compare>::upper_bound(start, finish, key, cmp); | ||||
|  | ||||
|         bool found_l = false; | ||||
|         bool found_u = false; | ||||
|         std::size_t index = 0; | ||||
|         std::size_t count = 0; | ||||
|         unsigned last_value = 0; | ||||
|         for (const_iterator p = start; p != finish; ++p) | ||||
|         { | ||||
|             if (p == l) | ||||
|                 found_l = true; | ||||
|              | ||||
|             if (p == u) | ||||
|             { | ||||
|                 assert(found_l); | ||||
|                 found_u = true; | ||||
|             } | ||||
|  | ||||
|             unsigned value = to_int(*p); | ||||
|             assert(value >= last_value); | ||||
|             last_value = value; | ||||
|              | ||||
|             if (!found_l) | ||||
|             { | ||||
|                 ++index; | ||||
|                 assert(to_int(*p) < key); | ||||
|             } | ||||
|             else if (!found_u) | ||||
|             { | ||||
|                 ++count; | ||||
|                 assert(to_int(*p) == key); | ||||
|             } | ||||
|             else | ||||
|                 assert(to_int(*p) > key); | ||||
|         } | ||||
|         assert(found_l || l == finish); | ||||
|         assert(found_u || u == finish); | ||||
|  | ||||
|         std::pair<const_iterator, const_iterator> | ||||
|             range = searches<Compare>::equal_range(start, finish, key, cmp); | ||||
|         assert(range.first == l); | ||||
|         assert(range.second == u); | ||||
|  | ||||
|         bool found = searches<Compare>::binary_search(start, finish, key, cmp); | ||||
|         assert(found == (u != l)); | ||||
|         std::cout << "found " << count << " copies of " << key << " at index " << index << "\n"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     string_vector x; | ||||
|     std::cout << "=== testing random-access iterators with <: ===\n"; | ||||
|     test_loop(x, no_compare(), 25); | ||||
|     std::cout << "=== testing random-access iterators with compare: ===\n"; | ||||
|     test_loop(x, cmp(), 25); | ||||
|      | ||||
|     std::list<mystring> y; | ||||
|     std::cout << "=== testing bidirectional iterators with <: ===\n"; | ||||
|     test_loop(y, no_compare(), 25); | ||||
|     std::cout << "=== testing bidirectional iterators with compare: ===\n"; | ||||
|     test_loop(y, cmp(), 25); | ||||
|     std::cerr << "******TEST PASSED******\n"; | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										643
									
								
								binary_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										643
									
								
								binary_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,643 @@ | ||||
| /*============================================================================= | ||||
|     Copyright (c) 2006, 2007 Matthew Calabrese | ||||
|  | ||||
|     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) | ||||
| ==============================================================================*/ | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
| #include <boost/utility/binary.hpp> | ||||
| #include <algorithm> | ||||
| #include <cstddef> | ||||
|  | ||||
| /* | ||||
| Note: This file tests every single valid bit-grouping on its own, and some | ||||
|       random combinations of bit-groupings. | ||||
| */ | ||||
|  | ||||
| std::size_t const num_random_test_values = 32; | ||||
|  | ||||
| // Note: These hex values should all correspond with the binary array below | ||||
| unsigned int const random_unsigned_ints_hex[num_random_test_values] | ||||
|   = { 0x0103u, 0x77ebu, 0x5f36u, 0x1f18u, 0xc530u, 0xa73au, 0xd6f8u, 0x0919u | ||||
|     , 0xfbb0u, 0x3e7cu, 0xd0e9u, 0x22c8u, 0x724eu, 0x14fau, 0xd98eu, 0x40b5 | ||||
|     , 0xeba0u, 0xfe50u, 0x688au, 0x1b05u, 0x5f9cu, 0xe4fcu, 0xa7b8u, 0xd3acu | ||||
|     , 0x1dddu, 0xbf04u, 0x8352u, 0xe89cu, 0x7506u, 0xe767u, 0xf489u, 0xe167 | ||||
|     }; | ||||
|  | ||||
| unsigned int const random_unsigned_ints_binary[num_random_test_values] | ||||
|   = { BOOST_BINARY( 0 00010000 0011 ), BOOST_BINARY( 0 11101 1111  101011 ) | ||||
|     , BOOST_BINARY( 010111 1100110 1 1 0 ), BOOST_BINARY( 000 1 11110 00 11000 ) | ||||
|     , BOOST_BINARY( 110 001010 0110 000 ), BOOST_BINARY( 1010 01110011 1010 ) | ||||
|     , BOOST_BINARY( 11 010 1 101111 1000 ), BOOST_BINARY( 0000 100100 0110 01 ) | ||||
|     , BOOST_BINARY( 1111 101110 11 0000 ), BOOST_BINARY( 00111110 01111100 ) | ||||
|     , BOOST_BINARY( 11  010 000111 01001 ), BOOST_BINARY( 00100 010110   01000 ) | ||||
|     , BOOST_BINARY( 01 11001001 001110 ), BOOST_BINARY( 0010 1001111 1010 ) | ||||
|     , BOOST_BINARY( 1101 1 00110 0 01110 ), BOOST_BINARY( 100 000 01011010 1 ) | ||||
|     , BOOST_BINARY( 11 1010 1110 1000 00 ), BOOST_BINARY( 11111 110010 10000 ) | ||||
|     , BOOST_BINARY( 01101 00010 001010 ), BOOST_BINARY( 000 11011 000001 01 ) | ||||
|     , BOOST_BINARY( 01 01111 1100111 00 ), BOOST_BINARY( 1 110010 0111111 00 ) | ||||
|     , BOOST_BINARY( 101 0011 11 01110 00 ), BOOST_BINARY( 110100 1 110101 100 ) | ||||
|     , BOOST_BINARY( 00 1110111 011 101 ), BOOST_BINARY( 1011 1111 00000 100 ) | ||||
|     , BOOST_BINARY( 1000 00110 101 0010 ), BOOST_BINARY( 1110  10001 001110 0 ) | ||||
|     , BOOST_BINARY( 011 1010100 000 110 ), BOOST_BINARY( 1110 0111 01100 111 ) | ||||
|     , BOOST_BINARY( 11110 10010 001001 ), BOOST_BINARY( 11 1000010 1100 111 ) | ||||
|     }; | ||||
|  | ||||
| unsigned int const unsigned_ints_1_bit[2] = | ||||
| { BOOST_BINARY( 0 ) | ||||
| , BOOST_BINARY( 1 ) | ||||
| }; | ||||
|  | ||||
| unsigned int const unsigned_ints_2_bits[4] = | ||||
| { BOOST_BINARY( 00 ) | ||||
| , BOOST_BINARY( 01 ) | ||||
| , BOOST_BINARY( 10 ) | ||||
| , BOOST_BINARY( 11 ) | ||||
| }; | ||||
|  | ||||
| unsigned int const unsigned_ints_3_bits[8] = | ||||
| { BOOST_BINARY( 000 ) | ||||
| , BOOST_BINARY( 001 ) | ||||
| , BOOST_BINARY( 010 ) | ||||
| , BOOST_BINARY( 011 ) | ||||
| , BOOST_BINARY( 100 ) | ||||
| , BOOST_BINARY( 101 ) | ||||
| , BOOST_BINARY( 110 ) | ||||
| , BOOST_BINARY( 111 ) | ||||
| }; | ||||
|  | ||||
| unsigned int const unsigned_ints_4_bits[16] = | ||||
| { BOOST_BINARY( 0000 ) | ||||
| , BOOST_BINARY( 0001 ) | ||||
| , BOOST_BINARY( 0010 ) | ||||
| , BOOST_BINARY( 0011 ) | ||||
| , BOOST_BINARY( 0100 ) | ||||
| , BOOST_BINARY( 0101 ) | ||||
| , BOOST_BINARY( 0110 ) | ||||
| , BOOST_BINARY( 0111 ) | ||||
| , BOOST_BINARY( 1000 ) | ||||
| , BOOST_BINARY( 1001 ) | ||||
| , BOOST_BINARY( 1010 ) | ||||
| , BOOST_BINARY( 1011 ) | ||||
| , BOOST_BINARY( 1100 ) | ||||
| , BOOST_BINARY( 1101 ) | ||||
| , BOOST_BINARY( 1110 ) | ||||
| , BOOST_BINARY( 1111 ) | ||||
| }; | ||||
|  | ||||
| unsigned int const unsigned_ints_5_bits[32] = | ||||
| { BOOST_BINARY( 00000 ) | ||||
| , BOOST_BINARY( 00001 ) | ||||
| , BOOST_BINARY( 00010 ) | ||||
| , BOOST_BINARY( 00011 ) | ||||
| , BOOST_BINARY( 00100 ) | ||||
| , BOOST_BINARY( 00101 ) | ||||
| , BOOST_BINARY( 00110 ) | ||||
| , BOOST_BINARY( 00111 ) | ||||
| , BOOST_BINARY( 01000 ) | ||||
| , BOOST_BINARY( 01001 ) | ||||
| , BOOST_BINARY( 01010 ) | ||||
| , BOOST_BINARY( 01011 ) | ||||
| , BOOST_BINARY( 01100 ) | ||||
| , BOOST_BINARY( 01101 ) | ||||
| , BOOST_BINARY( 01110 ) | ||||
| , BOOST_BINARY( 01111 ) | ||||
| , BOOST_BINARY( 10000 ) | ||||
| , BOOST_BINARY( 10001 ) | ||||
| , BOOST_BINARY( 10010 ) | ||||
| , BOOST_BINARY( 10011 ) | ||||
| , BOOST_BINARY( 10100 ) | ||||
| , BOOST_BINARY( 10101 ) | ||||
| , BOOST_BINARY( 10110 ) | ||||
| , BOOST_BINARY( 10111 ) | ||||
| , BOOST_BINARY( 11000 ) | ||||
| , BOOST_BINARY( 11001 ) | ||||
| , BOOST_BINARY( 11010 ) | ||||
| , BOOST_BINARY( 11011 ) | ||||
| , BOOST_BINARY( 11100 ) | ||||
| , BOOST_BINARY( 11101 ) | ||||
| , BOOST_BINARY( 11110 ) | ||||
| , BOOST_BINARY( 11111 ) | ||||
| }; | ||||
|  | ||||
| unsigned int const unsigned_ints_6_bits[64] = | ||||
| { BOOST_BINARY( 000000 ) | ||||
| , BOOST_BINARY( 000001 ) | ||||
| , BOOST_BINARY( 000010 ) | ||||
| , BOOST_BINARY( 000011 ) | ||||
| , BOOST_BINARY( 000100 ) | ||||
| , BOOST_BINARY( 000101 ) | ||||
| , BOOST_BINARY( 000110 ) | ||||
| , BOOST_BINARY( 000111 ) | ||||
| , BOOST_BINARY( 001000 ) | ||||
| , BOOST_BINARY( 001001 ) | ||||
| , BOOST_BINARY( 001010 ) | ||||
| , BOOST_BINARY( 001011 ) | ||||
| , BOOST_BINARY( 001100 ) | ||||
| , BOOST_BINARY( 001101 ) | ||||
| , BOOST_BINARY( 001110 ) | ||||
| , BOOST_BINARY( 001111 ) | ||||
| , BOOST_BINARY( 010000 ) | ||||
| , BOOST_BINARY( 010001 ) | ||||
| , BOOST_BINARY( 010010 ) | ||||
| , BOOST_BINARY( 010011 ) | ||||
| , BOOST_BINARY( 010100 ) | ||||
| , BOOST_BINARY( 010101 ) | ||||
| , BOOST_BINARY( 010110 ) | ||||
| , BOOST_BINARY( 010111 ) | ||||
| , BOOST_BINARY( 011000 ) | ||||
| , BOOST_BINARY( 011001 ) | ||||
| , BOOST_BINARY( 011010 ) | ||||
| , BOOST_BINARY( 011011 ) | ||||
| , BOOST_BINARY( 011100 ) | ||||
| , BOOST_BINARY( 011101 ) | ||||
| , BOOST_BINARY( 011110 ) | ||||
| , BOOST_BINARY( 011111 ) | ||||
| , BOOST_BINARY( 100000 ) | ||||
| , BOOST_BINARY( 100001 ) | ||||
| , BOOST_BINARY( 100010 ) | ||||
| , BOOST_BINARY( 100011 ) | ||||
| , BOOST_BINARY( 100100 ) | ||||
| , BOOST_BINARY( 100101 ) | ||||
| , BOOST_BINARY( 100110 ) | ||||
| , BOOST_BINARY( 100111 ) | ||||
| , BOOST_BINARY( 101000 ) | ||||
| , BOOST_BINARY( 101001 ) | ||||
| , BOOST_BINARY( 101010 ) | ||||
| , BOOST_BINARY( 101011 ) | ||||
| , BOOST_BINARY( 101100 ) | ||||
| , BOOST_BINARY( 101101 ) | ||||
| , BOOST_BINARY( 101110 ) | ||||
| , BOOST_BINARY( 101111 ) | ||||
| , BOOST_BINARY( 110000 ) | ||||
| , BOOST_BINARY( 110001 ) | ||||
| , BOOST_BINARY( 110010 ) | ||||
| , BOOST_BINARY( 110011 ) | ||||
| , BOOST_BINARY( 110100 ) | ||||
| , BOOST_BINARY( 110101 ) | ||||
| , BOOST_BINARY( 110110 ) | ||||
| , BOOST_BINARY( 110111 ) | ||||
| , BOOST_BINARY( 111000 ) | ||||
| , BOOST_BINARY( 111001 ) | ||||
| , BOOST_BINARY( 111010 ) | ||||
| , BOOST_BINARY( 111011 ) | ||||
| , BOOST_BINARY( 111100 ) | ||||
| , BOOST_BINARY( 111101 ) | ||||
| , BOOST_BINARY( 111110 ) | ||||
| , BOOST_BINARY( 111111 ) | ||||
| }; | ||||
|  | ||||
| unsigned int const unsigned_ints_7_bits[128] = | ||||
| { BOOST_BINARY( 0000000 ) | ||||
| , BOOST_BINARY( 0000001 ) | ||||
| , BOOST_BINARY( 0000010 ) | ||||
| , BOOST_BINARY( 0000011 ) | ||||
| , BOOST_BINARY( 0000100 ) | ||||
| , BOOST_BINARY( 0000101 ) | ||||
| , BOOST_BINARY( 0000110 ) | ||||
| , BOOST_BINARY( 0000111 ) | ||||
| , BOOST_BINARY( 0001000 ) | ||||
| , BOOST_BINARY( 0001001 ) | ||||
| , BOOST_BINARY( 0001010 ) | ||||
| , BOOST_BINARY( 0001011 ) | ||||
| , BOOST_BINARY( 0001100 ) | ||||
| , BOOST_BINARY( 0001101 ) | ||||
| , BOOST_BINARY( 0001110 ) | ||||
| , BOOST_BINARY( 0001111 ) | ||||
| , BOOST_BINARY( 0010000 ) | ||||
| , BOOST_BINARY( 0010001 ) | ||||
| , BOOST_BINARY( 0010010 ) | ||||
| , BOOST_BINARY( 0010011 ) | ||||
| , BOOST_BINARY( 0010100 ) | ||||
| , BOOST_BINARY( 0010101 ) | ||||
| , BOOST_BINARY( 0010110 ) | ||||
| , BOOST_BINARY( 0010111 ) | ||||
| , BOOST_BINARY( 0011000 ) | ||||
| , BOOST_BINARY( 0011001 ) | ||||
| , BOOST_BINARY( 0011010 ) | ||||
| , BOOST_BINARY( 0011011 ) | ||||
| , BOOST_BINARY( 0011100 ) | ||||
| , BOOST_BINARY( 0011101 ) | ||||
| , BOOST_BINARY( 0011110 ) | ||||
| , BOOST_BINARY( 0011111 ) | ||||
| , BOOST_BINARY( 0100000 ) | ||||
| , BOOST_BINARY( 0100001 ) | ||||
| , BOOST_BINARY( 0100010 ) | ||||
| , BOOST_BINARY( 0100011 ) | ||||
| , BOOST_BINARY( 0100100 ) | ||||
| , BOOST_BINARY( 0100101 ) | ||||
| , BOOST_BINARY( 0100110 ) | ||||
| , BOOST_BINARY( 0100111 ) | ||||
| , BOOST_BINARY( 0101000 ) | ||||
| , BOOST_BINARY( 0101001 ) | ||||
| , BOOST_BINARY( 0101010 ) | ||||
| , BOOST_BINARY( 0101011 ) | ||||
| , BOOST_BINARY( 0101100 ) | ||||
| , BOOST_BINARY( 0101101 ) | ||||
| , BOOST_BINARY( 0101110 ) | ||||
| , BOOST_BINARY( 0101111 ) | ||||
| , BOOST_BINARY( 0110000 ) | ||||
| , BOOST_BINARY( 0110001 ) | ||||
| , BOOST_BINARY( 0110010 ) | ||||
| , BOOST_BINARY( 0110011 ) | ||||
| , BOOST_BINARY( 0110100 ) | ||||
| , BOOST_BINARY( 0110101 ) | ||||
| , BOOST_BINARY( 0110110 ) | ||||
| , BOOST_BINARY( 0110111 ) | ||||
| , BOOST_BINARY( 0111000 ) | ||||
| , BOOST_BINARY( 0111001 ) | ||||
| , BOOST_BINARY( 0111010 ) | ||||
| , BOOST_BINARY( 0111011 ) | ||||
| , BOOST_BINARY( 0111100 ) | ||||
| , BOOST_BINARY( 0111101 ) | ||||
| , BOOST_BINARY( 0111110 ) | ||||
| , BOOST_BINARY( 0111111 ) | ||||
| , BOOST_BINARY( 1000000 ) | ||||
| , BOOST_BINARY( 1000001 ) | ||||
| , BOOST_BINARY( 1000010 ) | ||||
| , BOOST_BINARY( 1000011 ) | ||||
| , BOOST_BINARY( 1000100 ) | ||||
| , BOOST_BINARY( 1000101 ) | ||||
| , BOOST_BINARY( 1000110 ) | ||||
| , BOOST_BINARY( 1000111 ) | ||||
| , BOOST_BINARY( 1001000 ) | ||||
| , BOOST_BINARY( 1001001 ) | ||||
| , BOOST_BINARY( 1001010 ) | ||||
| , BOOST_BINARY( 1001011 ) | ||||
| , BOOST_BINARY( 1001100 ) | ||||
| , BOOST_BINARY( 1001101 ) | ||||
| , BOOST_BINARY( 1001110 ) | ||||
| , BOOST_BINARY( 1001111 ) | ||||
| , BOOST_BINARY( 1010000 ) | ||||
| , BOOST_BINARY( 1010001 ) | ||||
| , BOOST_BINARY( 1010010 ) | ||||
| , BOOST_BINARY( 1010011 ) | ||||
| , BOOST_BINARY( 1010100 ) | ||||
| , BOOST_BINARY( 1010101 ) | ||||
| , BOOST_BINARY( 1010110 ) | ||||
| , BOOST_BINARY( 1010111 ) | ||||
| , BOOST_BINARY( 1011000 ) | ||||
| , BOOST_BINARY( 1011001 ) | ||||
| , BOOST_BINARY( 1011010 ) | ||||
| , BOOST_BINARY( 1011011 ) | ||||
| , BOOST_BINARY( 1011100 ) | ||||
| , BOOST_BINARY( 1011101 ) | ||||
| , BOOST_BINARY( 1011110 ) | ||||
| , BOOST_BINARY( 1011111 ) | ||||
| , BOOST_BINARY( 1100000 ) | ||||
| , BOOST_BINARY( 1100001 ) | ||||
| , BOOST_BINARY( 1100010 ) | ||||
| , BOOST_BINARY( 1100011 ) | ||||
| , BOOST_BINARY( 1100100 ) | ||||
| , BOOST_BINARY( 1100101 ) | ||||
| , BOOST_BINARY( 1100110 ) | ||||
| , BOOST_BINARY( 1100111 ) | ||||
| , BOOST_BINARY( 1101000 ) | ||||
| , BOOST_BINARY( 1101001 ) | ||||
| , BOOST_BINARY( 1101010 ) | ||||
| , BOOST_BINARY( 1101011 ) | ||||
| , BOOST_BINARY( 1101100 ) | ||||
| , BOOST_BINARY( 1101101 ) | ||||
| , BOOST_BINARY( 1101110 ) | ||||
| , BOOST_BINARY( 1101111 ) | ||||
| , BOOST_BINARY( 1110000 ) | ||||
| , BOOST_BINARY( 1110001 ) | ||||
| , BOOST_BINARY( 1110010 ) | ||||
| , BOOST_BINARY( 1110011 ) | ||||
| , BOOST_BINARY( 1110100 ) | ||||
| , BOOST_BINARY( 1110101 ) | ||||
| , BOOST_BINARY( 1110110 ) | ||||
| , BOOST_BINARY( 1110111 ) | ||||
| , BOOST_BINARY( 1111000 ) | ||||
| , BOOST_BINARY( 1111001 ) | ||||
| , BOOST_BINARY( 1111010 ) | ||||
| , BOOST_BINARY( 1111011 ) | ||||
| , BOOST_BINARY( 1111100 ) | ||||
| , BOOST_BINARY( 1111101 ) | ||||
| , BOOST_BINARY( 1111110 ) | ||||
| , BOOST_BINARY( 1111111 ) | ||||
| }; | ||||
| unsigned int const unsigned_ints_8_bits[256] = | ||||
| { BOOST_BINARY( 00000000 ) | ||||
| , BOOST_BINARY( 00000001 ) | ||||
| , BOOST_BINARY( 00000010 ) | ||||
| , BOOST_BINARY( 00000011 ) | ||||
| , BOOST_BINARY( 00000100 ) | ||||
| , BOOST_BINARY( 00000101 ) | ||||
| , BOOST_BINARY( 00000110 ) | ||||
| , BOOST_BINARY( 00000111 ) | ||||
| , BOOST_BINARY( 00001000 ) | ||||
| , BOOST_BINARY( 00001001 ) | ||||
| , BOOST_BINARY( 00001010 ) | ||||
| , BOOST_BINARY( 00001011 ) | ||||
| , BOOST_BINARY( 00001100 ) | ||||
| , BOOST_BINARY( 00001101 ) | ||||
| , BOOST_BINARY( 00001110 ) | ||||
| , BOOST_BINARY( 00001111 ) | ||||
| , BOOST_BINARY( 00010000 ) | ||||
| , BOOST_BINARY( 00010001 ) | ||||
| , BOOST_BINARY( 00010010 ) | ||||
| , BOOST_BINARY( 00010011 ) | ||||
| , BOOST_BINARY( 00010100 ) | ||||
| , BOOST_BINARY( 00010101 ) | ||||
| , BOOST_BINARY( 00010110 ) | ||||
| , BOOST_BINARY( 00010111 ) | ||||
| , BOOST_BINARY( 00011000 ) | ||||
| , BOOST_BINARY( 00011001 ) | ||||
| , BOOST_BINARY( 00011010 ) | ||||
| , BOOST_BINARY( 00011011 ) | ||||
| , BOOST_BINARY( 00011100 ) | ||||
| , BOOST_BINARY( 00011101 ) | ||||
| , BOOST_BINARY( 00011110 ) | ||||
| , BOOST_BINARY( 00011111 ) | ||||
| , BOOST_BINARY( 00100000 ) | ||||
| , BOOST_BINARY( 00100001 ) | ||||
| , BOOST_BINARY( 00100010 ) | ||||
| , BOOST_BINARY( 00100011 ) | ||||
| , BOOST_BINARY( 00100100 ) | ||||
| , BOOST_BINARY( 00100101 ) | ||||
| , BOOST_BINARY( 00100110 ) | ||||
| , BOOST_BINARY( 00100111 ) | ||||
| , BOOST_BINARY( 00101000 ) | ||||
| , BOOST_BINARY( 00101001 ) | ||||
| , BOOST_BINARY( 00101010 ) | ||||
| , BOOST_BINARY( 00101011 ) | ||||
| , BOOST_BINARY( 00101100 ) | ||||
| , BOOST_BINARY( 00101101 ) | ||||
| , BOOST_BINARY( 00101110 ) | ||||
| , BOOST_BINARY( 00101111 ) | ||||
| , BOOST_BINARY( 00110000 ) | ||||
| , BOOST_BINARY( 00110001 ) | ||||
| , BOOST_BINARY( 00110010 ) | ||||
| , BOOST_BINARY( 00110011 ) | ||||
| , BOOST_BINARY( 00110100 ) | ||||
| , BOOST_BINARY( 00110101 ) | ||||
| , BOOST_BINARY( 00110110 ) | ||||
| , BOOST_BINARY( 00110111 ) | ||||
| , BOOST_BINARY( 00111000 ) | ||||
| , BOOST_BINARY( 00111001 ) | ||||
| , BOOST_BINARY( 00111010 ) | ||||
| , BOOST_BINARY( 00111011 ) | ||||
| , BOOST_BINARY( 00111100 ) | ||||
| , BOOST_BINARY( 00111101 ) | ||||
| , BOOST_BINARY( 00111110 ) | ||||
| , BOOST_BINARY( 00111111 ) | ||||
| , BOOST_BINARY( 01000000 ) | ||||
| , BOOST_BINARY( 01000001 ) | ||||
| , BOOST_BINARY( 01000010 ) | ||||
| , BOOST_BINARY( 01000011 ) | ||||
| , BOOST_BINARY( 01000100 ) | ||||
| , BOOST_BINARY( 01000101 ) | ||||
| , BOOST_BINARY( 01000110 ) | ||||
| , BOOST_BINARY( 01000111 ) | ||||
| , BOOST_BINARY( 01001000 ) | ||||
| , BOOST_BINARY( 01001001 ) | ||||
| , BOOST_BINARY( 01001010 ) | ||||
| , BOOST_BINARY( 01001011 ) | ||||
| , BOOST_BINARY( 01001100 ) | ||||
| , BOOST_BINARY( 01001101 ) | ||||
| , BOOST_BINARY( 01001110 ) | ||||
| , BOOST_BINARY( 01001111 ) | ||||
| , BOOST_BINARY( 01010000 ) | ||||
| , BOOST_BINARY( 01010001 ) | ||||
| , BOOST_BINARY( 01010010 ) | ||||
| , BOOST_BINARY( 01010011 ) | ||||
| , BOOST_BINARY( 01010100 ) | ||||
| , BOOST_BINARY( 01010101 ) | ||||
| , BOOST_BINARY( 01010110 ) | ||||
| , BOOST_BINARY( 01010111 ) | ||||
| , BOOST_BINARY( 01011000 ) | ||||
| , BOOST_BINARY( 01011001 ) | ||||
| , BOOST_BINARY( 01011010 ) | ||||
| , BOOST_BINARY( 01011011 ) | ||||
| , BOOST_BINARY( 01011100 ) | ||||
| , BOOST_BINARY( 01011101 ) | ||||
| , BOOST_BINARY( 01011110 ) | ||||
| , BOOST_BINARY( 01011111 ) | ||||
| , BOOST_BINARY( 01100000 ) | ||||
| , BOOST_BINARY( 01100001 ) | ||||
| , BOOST_BINARY( 01100010 ) | ||||
| , BOOST_BINARY( 01100011 ) | ||||
| , BOOST_BINARY( 01100100 ) | ||||
| , BOOST_BINARY( 01100101 ) | ||||
| , BOOST_BINARY( 01100110 ) | ||||
| , BOOST_BINARY( 01100111 ) | ||||
| , BOOST_BINARY( 01101000 ) | ||||
| , BOOST_BINARY( 01101001 ) | ||||
| , BOOST_BINARY( 01101010 ) | ||||
| , BOOST_BINARY( 01101011 ) | ||||
| , BOOST_BINARY( 01101100 ) | ||||
| , BOOST_BINARY( 01101101 ) | ||||
| , BOOST_BINARY( 01101110 ) | ||||
| , BOOST_BINARY( 01101111 ) | ||||
| , BOOST_BINARY( 01110000 ) | ||||
| , BOOST_BINARY( 01110001 ) | ||||
| , BOOST_BINARY( 01110010 ) | ||||
| , BOOST_BINARY( 01110011 ) | ||||
| , BOOST_BINARY( 01110100 ) | ||||
| , BOOST_BINARY( 01110101 ) | ||||
| , BOOST_BINARY( 01110110 ) | ||||
| , BOOST_BINARY( 01110111 ) | ||||
| , BOOST_BINARY( 01111000 ) | ||||
| , BOOST_BINARY( 01111001 ) | ||||
| , BOOST_BINARY( 01111010 ) | ||||
| , BOOST_BINARY( 01111011 ) | ||||
| , BOOST_BINARY( 01111100 ) | ||||
| , BOOST_BINARY( 01111101 ) | ||||
| , BOOST_BINARY( 01111110 ) | ||||
| , BOOST_BINARY( 01111111 ) | ||||
| , BOOST_BINARY( 10000000 ) | ||||
| , BOOST_BINARY( 10000001 ) | ||||
| , BOOST_BINARY( 10000010 ) | ||||
| , BOOST_BINARY( 10000011 ) | ||||
| , BOOST_BINARY( 10000100 ) | ||||
| , BOOST_BINARY( 10000101 ) | ||||
| , BOOST_BINARY( 10000110 ) | ||||
| , BOOST_BINARY( 10000111 ) | ||||
| , BOOST_BINARY( 10001000 ) | ||||
| , BOOST_BINARY( 10001001 ) | ||||
| , BOOST_BINARY( 10001010 ) | ||||
| , BOOST_BINARY( 10001011 ) | ||||
| , BOOST_BINARY( 10001100 ) | ||||
| , BOOST_BINARY( 10001101 ) | ||||
| , BOOST_BINARY( 10001110 ) | ||||
| , BOOST_BINARY( 10001111 ) | ||||
| , BOOST_BINARY( 10010000 ) | ||||
| , BOOST_BINARY( 10010001 ) | ||||
| , BOOST_BINARY( 10010010 ) | ||||
| , BOOST_BINARY( 10010011 ) | ||||
| , BOOST_BINARY( 10010100 ) | ||||
| , BOOST_BINARY( 10010101 ) | ||||
| , BOOST_BINARY( 10010110 ) | ||||
| , BOOST_BINARY( 10010111 ) | ||||
| , BOOST_BINARY( 10011000 ) | ||||
| , BOOST_BINARY( 10011001 ) | ||||
| , BOOST_BINARY( 10011010 ) | ||||
| , BOOST_BINARY( 10011011 ) | ||||
| , BOOST_BINARY( 10011100 ) | ||||
| , BOOST_BINARY( 10011101 ) | ||||
| , BOOST_BINARY( 10011110 ) | ||||
| , BOOST_BINARY( 10011111 ) | ||||
| , BOOST_BINARY( 10100000 ) | ||||
| , BOOST_BINARY( 10100001 ) | ||||
| , BOOST_BINARY( 10100010 ) | ||||
| , BOOST_BINARY( 10100011 ) | ||||
| , BOOST_BINARY( 10100100 ) | ||||
| , BOOST_BINARY( 10100101 ) | ||||
| , BOOST_BINARY( 10100110 ) | ||||
| , BOOST_BINARY( 10100111 ) | ||||
| , BOOST_BINARY( 10101000 ) | ||||
| , BOOST_BINARY( 10101001 ) | ||||
| , BOOST_BINARY( 10101010 ) | ||||
| , BOOST_BINARY( 10101011 ) | ||||
| , BOOST_BINARY( 10101100 ) | ||||
| , BOOST_BINARY( 10101101 ) | ||||
| , BOOST_BINARY( 10101110 ) | ||||
| , BOOST_BINARY( 10101111 ) | ||||
| , BOOST_BINARY( 10110000 ) | ||||
| , BOOST_BINARY( 10110001 ) | ||||
| , BOOST_BINARY( 10110010 ) | ||||
| , BOOST_BINARY( 10110011 ) | ||||
| , BOOST_BINARY( 10110100 ) | ||||
| , BOOST_BINARY( 10110101 ) | ||||
| , BOOST_BINARY( 10110110 ) | ||||
| , BOOST_BINARY( 10110111 ) | ||||
| , BOOST_BINARY( 10111000 ) | ||||
| , BOOST_BINARY( 10111001 ) | ||||
| , BOOST_BINARY( 10111010 ) | ||||
| , BOOST_BINARY( 10111011 ) | ||||
| , BOOST_BINARY( 10111100 ) | ||||
| , BOOST_BINARY( 10111101 ) | ||||
| , BOOST_BINARY( 10111110 ) | ||||
| , BOOST_BINARY( 10111111 ) | ||||
| , BOOST_BINARY( 11000000 ) | ||||
| , BOOST_BINARY( 11000001 ) | ||||
| , BOOST_BINARY( 11000010 ) | ||||
| , BOOST_BINARY( 11000011 ) | ||||
| , BOOST_BINARY( 11000100 ) | ||||
| , BOOST_BINARY( 11000101 ) | ||||
| , BOOST_BINARY( 11000110 ) | ||||
| , BOOST_BINARY( 11000111 ) | ||||
| , BOOST_BINARY( 11001000 ) | ||||
| , BOOST_BINARY( 11001001 ) | ||||
| , BOOST_BINARY( 11001010 ) | ||||
| , BOOST_BINARY( 11001011 ) | ||||
| , BOOST_BINARY( 11001100 ) | ||||
| , BOOST_BINARY( 11001101 ) | ||||
| , BOOST_BINARY( 11001110 ) | ||||
| , BOOST_BINARY( 11001111 ) | ||||
| , BOOST_BINARY( 11010000 ) | ||||
| , BOOST_BINARY( 11010001 ) | ||||
| , BOOST_BINARY( 11010010 ) | ||||
| , BOOST_BINARY( 11010011 ) | ||||
| , BOOST_BINARY( 11010100 ) | ||||
| , BOOST_BINARY( 11010101 ) | ||||
| , BOOST_BINARY( 11010110 ) | ||||
| , BOOST_BINARY( 11010111 ) | ||||
| , BOOST_BINARY( 11011000 ) | ||||
| , BOOST_BINARY( 11011001 ) | ||||
| , BOOST_BINARY( 11011010 ) | ||||
| , BOOST_BINARY( 11011011 ) | ||||
| , BOOST_BINARY( 11011100 ) | ||||
| , BOOST_BINARY( 11011101 ) | ||||
| , BOOST_BINARY( 11011110 ) | ||||
| , BOOST_BINARY( 11011111 ) | ||||
| , BOOST_BINARY( 11100000 ) | ||||
| , BOOST_BINARY( 11100001 ) | ||||
| , BOOST_BINARY( 11100010 ) | ||||
| , BOOST_BINARY( 11100011 ) | ||||
| , BOOST_BINARY( 11100100 ) | ||||
| , BOOST_BINARY( 11100101 ) | ||||
| , BOOST_BINARY( 11100110 ) | ||||
| , BOOST_BINARY( 11100111 ) | ||||
| , BOOST_BINARY( 11101000 ) | ||||
| , BOOST_BINARY( 11101001 ) | ||||
| , BOOST_BINARY( 11101010 ) | ||||
| , BOOST_BINARY( 11101011 ) | ||||
| , BOOST_BINARY( 11101100 ) | ||||
| , BOOST_BINARY( 11101101 ) | ||||
| , BOOST_BINARY( 11101110 ) | ||||
| , BOOST_BINARY( 11101111 ) | ||||
| , BOOST_BINARY( 11110000 ) | ||||
| , BOOST_BINARY( 11110001 ) | ||||
| , BOOST_BINARY( 11110010 ) | ||||
| , BOOST_BINARY( 11110011 ) | ||||
| , BOOST_BINARY( 11110100 ) | ||||
| , BOOST_BINARY( 11110101 ) | ||||
| , BOOST_BINARY( 11110110 ) | ||||
| , BOOST_BINARY( 11110111 ) | ||||
| , BOOST_BINARY( 11111000 ) | ||||
| , BOOST_BINARY( 11111001 ) | ||||
| , BOOST_BINARY( 11111010 ) | ||||
| , BOOST_BINARY( 11111011 ) | ||||
| , BOOST_BINARY( 11111100 ) | ||||
| , BOOST_BINARY( 11111101 ) | ||||
| , BOOST_BINARY( 11111110 ) | ||||
| , BOOST_BINARY( 11111111 ) | ||||
| }; | ||||
|  | ||||
| struct left_is_not_one_less_than_right | ||||
| { | ||||
|   bool operator ()( unsigned int left, unsigned int right ) const | ||||
|   { | ||||
|     return right != left + 1; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template< std::size_t Size > | ||||
| bool is_ascending_from_0_array( unsigned int const (&array)[Size] ) | ||||
| { | ||||
|   unsigned int const* const curr = array, | ||||
|                     * const end  = array + Size; | ||||
|  | ||||
|   return    ( *curr == 0 ) | ||||
|          && (    std::adjacent_find( curr, end | ||||
|                                    , left_is_not_one_less_than_right() | ||||
|                                    ) | ||||
|               == end | ||||
|             ); | ||||
| } | ||||
|  | ||||
| std::size_t const unsigned_int_id = 1, | ||||
|                   unsigned_long_int_id = 2; | ||||
|  | ||||
| typedef char (&unsigned_int_id_type)[unsigned_int_id]; | ||||
| typedef char (&unsigned_long_int_id_type)[unsigned_long_int_id]; | ||||
|  | ||||
| // Note: Functions only used for type checking | ||||
| unsigned_int_id_type      binary_type_checker( unsigned int ); | ||||
| unsigned_long_int_id_type binary_type_checker( unsigned long int ); | ||||
|  | ||||
| int test_main( int, char *[] ) | ||||
| { | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_1_bit ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_2_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_3_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_4_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_5_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_6_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_7_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_8_bits ) ); | ||||
|  | ||||
|   BOOST_CHECK( std::equal( &random_unsigned_ints_hex[0] | ||||
|                          , random_unsigned_ints_hex + num_random_test_values | ||||
|                          , &random_unsigned_ints_binary[0] | ||||
|                          ) | ||||
|              ); | ||||
|  | ||||
|   BOOST_CHECK(    sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) ) | ||||
|                == unsigned_int_id | ||||
|              ); | ||||
|  | ||||
|   BOOST_CHECK(    sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) ) | ||||
|                == unsigned_long_int_id | ||||
|              ); | ||||
|  | ||||
|   BOOST_CHECK(    sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) ) | ||||
|                == unsigned_long_int_id | ||||
|              ); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| @@ -12,7 +12,7 @@ content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot"> | ||||
| <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" | ||||
| vlink="#800080"> | ||||
|  | ||||
| <h1><img src="../../c++boost.gif" width="276" height="86">Header | ||||
| <h1><img src="../../boost.png" 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 | ||||
| @@ -592,7 +592,8 @@ would prevent template argument deduction from functioning.</p> | ||||
| <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>), | ||||
| following example (see <a | ||||
| href="../type_traits/examples/fill_example.cpp">fill_example.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 | ||||
| @@ -605,7 +606,7 @@ 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); | ||||
|    static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val) | ||||
|    { | ||||
|       while(first != last) | ||||
|       { | ||||
| @@ -739,24 +740,16 @@ specialisation).</p> | ||||
|  | ||||
| <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> | ||||
|    <p> | ||||
|       Copyright 2000 Steve Cleary, Beman Dawes, Howard | ||||
|       Hinnant and John Maddock. <br/> | ||||
|       Use, modification and distribution are subject to the | ||||
|       Boost Software License, Version 1.0. | ||||
|       (See accompanying file LICENSE_1_0.txt | ||||
|       or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> | ||||
|          http://www.boost.org/LICENSE_1_0.txt | ||||
|       </a>). | ||||
|    </p> | ||||
| </body> | ||||
| </html> | ||||
|  | ||||
|   | ||||
| @@ -1,22 +1,29 @@ | ||||
|  // boost::compressed_pair test program    | ||||
| //  boost::compressed_pair test program    | ||||
|      | ||||
|  //  (C) Copyright John Maddock 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.    | ||||
| //  (C) Copyright John Maddock 2000.  | ||||
| //  Use, modification and distribution are subject to the Boost Software License, | ||||
| //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt). | ||||
|  | ||||
|  | ||||
| // standalone test program for <boost/call_traits.hpp> | ||||
| // 18 Mar 2002: | ||||
| //    Changed some names to prevent conflicts with some new type_traits additions. | ||||
| // 03 Oct 2000: | ||||
| //    Enabled extra tests for VC6. | ||||
|  | ||||
| #include <cassert> | ||||
| #include <iostream> | ||||
| #include <iomanip> | ||||
| #include <algorithm> | ||||
| #include <typeinfo> | ||||
| #include <boost/call_traits.hpp> | ||||
|  | ||||
| #include <boost/type_traits/type_traits_test.hpp> | ||||
| #include <libs/type_traits/test/test.hpp> | ||||
| #include <libs/type_traits/test/check_type.hpp> | ||||
|  | ||||
| // a way prevent warnings for unused variables | ||||
| template<class T> inline void unused_variable(const T&) {} | ||||
|  | ||||
| // | ||||
| // struct contained models a type that contains a type (for example std::pair) | ||||
| // arrays are contained by value, and have to be treated as a special case: | ||||
| @@ -44,7 +51,7 @@ struct contained | ||||
|    reference get() { return v_; } | ||||
|    const_reference const_get()const { return v_; } | ||||
|    // pass value: | ||||
|    void call(param_type p){} | ||||
|    void call(param_type){} | ||||
|  | ||||
| }; | ||||
|  | ||||
| @@ -69,12 +76,12 @@ struct contained<T[N]> | ||||
|    // return by_ref: | ||||
|    reference get() { return v_; } | ||||
|    const_reference const_get()const { return v_; } | ||||
|    void call(param_type p){} | ||||
|    void call(param_type){} | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| template <class T> | ||||
| contained<typename boost::call_traits<T>::value_type> wrap(const T& t) | ||||
| contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t) | ||||
| { | ||||
|    typedef typename boost::call_traits<T>::value_type ct; | ||||
|    return contained<ct>(t); | ||||
| @@ -114,9 +121,9 @@ void call_traits_checker<T>::operator()(param_type p) | ||||
|    T t(p); | ||||
|    contained<T> c(t); | ||||
|    cout << "checking contained<" << typeid(T).name() << ">..." << endl; | ||||
|    assert(t == c.value()); | ||||
|    assert(t == c.get()); | ||||
|    assert(t == c.const_get()); | ||||
|    BOOST_CHECK(t == c.value()); | ||||
|    BOOST_CHECK(t == c.get()); | ||||
|    BOOST_CHECK(t == c.const_get()); | ||||
| #ifndef __ICL | ||||
|    //cout << "typeof contained<" << typeid(T).name() << ">::v_ is:           " << typeid(&contained<T>::v_).name() << endl; | ||||
|    cout << "typeof contained<" << typeid(T).name() << ">::value() is:      " << typeid(&contained<T>::value).name() << endl; | ||||
| @@ -138,11 +145,11 @@ struct call_traits_checker<T[N]> | ||||
|       cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl; | ||||
|       unsigned int i = 0; | ||||
|       for(i = 0; i < N; ++i) | ||||
|          assert(t[i] == c.value()[i]); | ||||
|          BOOST_CHECK(t[i] == c.value()[i]); | ||||
|       for(i = 0; i < N; ++i) | ||||
|          assert(t[i] == c.get()[i]); | ||||
|          BOOST_CHECK(t[i] == c.get()[i]); | ||||
|       for(i = 0; i < N; ++i) | ||||
|          assert(t[i] == c.const_get()[i]); | ||||
|          BOOST_CHECK(t[i] == c.const_get()[i]); | ||||
|  | ||||
|       cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is:         " << typeid(&contained<T[N]>::v_).name() << endl; | ||||
|       cout << "typeof contained<" << typeid(T[N]).name() << ">::value is:      " << typeid(&contained<T[N]>::value).name() << endl; | ||||
| @@ -156,11 +163,11 @@ struct call_traits_checker<T[N]> | ||||
|  | ||||
| // | ||||
| // check_wrap: | ||||
| template <class T, class U> | ||||
| void check_wrap(const contained<T>& w, const U& u) | ||||
| template <class W, class U> | ||||
| void check_wrap(const W& w, const U& u) | ||||
| { | ||||
|    cout << "checking contained<" << typeid(T).name() << ">..." << endl; | ||||
|    assert(w.value() == u); | ||||
|    cout << "checking " << typeid(W).name() << "..." << endl; | ||||
|    BOOST_CHECK(w.value() == u); | ||||
| } | ||||
|  | ||||
| // | ||||
| @@ -171,8 +178,8 @@ template <class T, class U, class V> | ||||
| void check_make_pair(T c, U u, V v) | ||||
| { | ||||
|    cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl; | ||||
|    assert(c.first == u); | ||||
|    assert(c.second == v); | ||||
|    BOOST_CHECK(c.first == u); | ||||
|    BOOST_CHECK(c.second == v); | ||||
|    cout << endl; | ||||
| } | ||||
|  | ||||
| @@ -181,6 +188,12 @@ struct comparible_UDT | ||||
| { | ||||
|    int i_; | ||||
|    comparible_UDT() : i_(2){} | ||||
|    comparible_UDT(const comparible_UDT& other) : i_(other.i_){} | ||||
|    comparible_UDT& operator=(const comparible_UDT& other) | ||||
|    {  | ||||
|       i_ = other.i_; | ||||
|       return *this; | ||||
|    } | ||||
|    bool operator == (const comparible_UDT& v){ return v.i_ == i_; } | ||||
| }; | ||||
|  | ||||
| @@ -193,26 +206,23 @@ int main(int argc, char *argv[ ]) | ||||
|    int i = 2; | ||||
|    c2(i); | ||||
|    int* pi = &i; | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) | ||||
|    int a[2] = {1,2}; | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL) | ||||
|    call_traits_checker<int*> c3; | ||||
|    c3(pi); | ||||
|    call_traits_checker<int&> c4; | ||||
|    c4(i); | ||||
|    call_traits_checker<const int&> c5; | ||||
|    c5(i); | ||||
| #if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) | ||||
|    int a[2] = {1,2}; | ||||
| #if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC) | ||||
|    call_traits_checker<int[2]> c6; | ||||
|    c6(a); | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
|    check_wrap(wrap(2), 2); | ||||
|    const char ca[4] = "abc"; | ||||
|    // compiler can't deduce this for some reason: | ||||
|    //check_wrap(wrap(ca), ca); | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|    check_wrap(wrap(a), a); | ||||
|    check_wrap(test_wrap_type(2), 2); | ||||
| #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) | ||||
|    check_wrap(test_wrap_type(a), a); | ||||
|    check_make_pair(test::make_pair(a, a), a, a); | ||||
| #endif | ||||
|  | ||||
| @@ -221,63 +231,67 @@ int main(int argc, char *argv[ ]) | ||||
|    typedef int& r_type; | ||||
|    typedef const r_type cr_type; | ||||
|  | ||||
|    type_test(comparible_UDT, boost::call_traits<comparible_UDT>::value_type) | ||||
|    type_test(comparible_UDT&, boost::call_traits<comparible_UDT>::reference) | ||||
|    type_test(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference) | ||||
|    type_test(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type) | ||||
|    type_test(int, boost::call_traits<int>::value_type) | ||||
|    type_test(int&, boost::call_traits<int>::reference) | ||||
|    type_test(const int&, boost::call_traits<int>::const_reference) | ||||
|    type_test(const int, boost::call_traits<int>::param_type) | ||||
|    type_test(int*, boost::call_traits<int*>::value_type) | ||||
|    type_test(int*&, boost::call_traits<int*>::reference) | ||||
|    type_test(int*const&, boost::call_traits<int*>::const_reference) | ||||
|    type_test(int*const, boost::call_traits<int*>::param_type) | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) | ||||
|    type_test(int&, boost::call_traits<int&>::value_type) | ||||
|    type_test(int&, boost::call_traits<int&>::reference) | ||||
|    type_test(const int&, boost::call_traits<int&>::const_reference) | ||||
|    type_test(int&, boost::call_traits<int&>::param_type) | ||||
| #if !(defined(__GNUC__) && (__GNUC__ < 3)) | ||||
|    type_test(int&, boost::call_traits<cr_type>::value_type) | ||||
|    type_test(int&, boost::call_traits<cr_type>::reference) | ||||
|    type_test(const int&, boost::call_traits<cr_type>::const_reference) | ||||
|    type_test(int&, boost::call_traits<cr_type>::param_type) | ||||
|    BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type); | ||||
|    BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference); | ||||
|    BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference); | ||||
|    BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type); | ||||
|    BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type); | ||||
|    BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference); | ||||
|    BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference); | ||||
|    BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type); | ||||
|    BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type); | ||||
|    BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference); | ||||
|    BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference); | ||||
|    BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type); | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) | ||||
|    BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type); | ||||
|    BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference); | ||||
|    BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference); | ||||
|    BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type); | ||||
| #if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1))) | ||||
|    BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type); | ||||
|    BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference); | ||||
|    BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference); | ||||
|    BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type); | ||||
| #else | ||||
|    std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl; | ||||
|    failures += 4; | ||||
|    test_count += 4; | ||||
| #endif | ||||
|    type_test(const int&, boost::call_traits<const int&>::value_type) | ||||
|    type_test(const int&, boost::call_traits<const int&>::reference) | ||||
|    type_test(const int&, boost::call_traits<const int&>::const_reference) | ||||
|    type_test(const int&, boost::call_traits<const int&>::param_type) | ||||
|    BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type); | ||||
|    BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference); | ||||
|    BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference); | ||||
|    BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type); | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|    type_test(const int*, boost::call_traits<int[3]>::value_type) | ||||
|    type_test(int(&)[3], boost::call_traits<int[3]>::reference) | ||||
|    type_test(const int(&)[3], boost::call_traits<int[3]>::const_reference) | ||||
|    type_test(const int*const, boost::call_traits<int[3]>::param_type) | ||||
|    type_test(const int*, boost::call_traits<const int[3]>::value_type) | ||||
|    type_test(const int(&)[3], boost::call_traits<const int[3]>::reference) | ||||
|    type_test(const int(&)[3], boost::call_traits<const int[3]>::const_reference) | ||||
|    type_test(const int*const, boost::call_traits<const int[3]>::param_type) | ||||
|    BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type); | ||||
|    BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference); | ||||
|    BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference); | ||||
|    BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type); | ||||
|    BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type); | ||||
|    BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference); | ||||
|    BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference); | ||||
|    BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type); | ||||
|    // test with abstract base class: | ||||
|    BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type); | ||||
|    BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference); | ||||
|    BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference); | ||||
|    BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type); | ||||
| #else | ||||
|    std::cout << "You're compiler does not support partial template instantiation, skipping 8 tests (8 errors)" << std::endl; | ||||
|    failures += 8; | ||||
|    test_count += 8; | ||||
|    std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl; | ||||
| #endif | ||||
| #else | ||||
|    std::cout << "You're compiler does not support partial template instantiation, skipping 20 tests (20 errors)" << std::endl; | ||||
|    failures += 20; | ||||
|    test_count += 20; | ||||
|    std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl; | ||||
| #endif | ||||
|    // test with an incomplete type: | ||||
|    BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type); | ||||
|    BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference); | ||||
|    BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference); | ||||
|    BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type); | ||||
|  | ||||
|    return check_result(argc, argv); | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
| // | ||||
| // define call_traits tests to check that the assertions in the docs do actually work | ||||
| // this is an instantiate only set of tests: | ||||
| // this is an compile-time only set of tests: | ||||
| // | ||||
| template <typename T, bool isarray = false> | ||||
| struct call_traits_test | ||||
| @@ -312,6 +326,19 @@ void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, | ||||
|    param_type p2(v); | ||||
|    param_type p3(r); | ||||
|    param_type p4(p); | ||||
|     | ||||
|    unused_variable(v2); | ||||
|    unused_variable(v3); | ||||
|    unused_variable(v4); | ||||
|    unused_variable(r2); | ||||
|    unused_variable(r3); | ||||
|    unused_variable(cr2); | ||||
|    unused_variable(cr3); | ||||
|    unused_variable(cr4); | ||||
|    unused_variable(cr5); | ||||
|    unused_variable(p2); | ||||
|    unused_variable(p3); | ||||
|    unused_variable(p4); | ||||
| } | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
| template <typename T> | ||||
| @@ -348,6 +375,19 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>: | ||||
|    param_type p2(v); | ||||
|    param_type p3(r); | ||||
|    param_type p4(p); | ||||
|     | ||||
|    unused_variable(v2); | ||||
|    unused_variable(v3); | ||||
|    unused_variable(v4); | ||||
|    unused_variable(v5); | ||||
| #ifndef __BORLANDC__ | ||||
|    unused_variable(r2); | ||||
|    unused_variable(cr2); | ||||
| #endif | ||||
|    unused_variable(cr3); | ||||
|    unused_variable(p2); | ||||
|    unused_variable(p3); | ||||
|    unused_variable(p4); | ||||
| } | ||||
| #endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
| // | ||||
| @@ -355,23 +395,11 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>: | ||||
| template struct call_traits_test<int>; | ||||
| template struct call_traits_test<const int>; | ||||
| template struct call_traits_test<int*>; | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) | ||||
| template struct call_traits_test<int&>; | ||||
| template struct call_traits_test<const int&>; | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
| #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) | ||||
| template struct call_traits_test<int[2], true>; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| unsigned int expected_failures = 10; | ||||
| #elif defined(__BORLANDC__) | ||||
| unsigned int expected_failures = 2; | ||||
| #elif defined(__GNUC__) | ||||
| unsigned int expected_failures = 4; | ||||
| #else | ||||
| unsigned int expected_failures = 0; | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										122
									
								
								checked_delete.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								checked_delete.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | ||||
| <html> | ||||
| 	<head> | ||||
| 		<title>Boost: checked_delete.hpp documentation</title> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||||
| 	</head> | ||||
| 	<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> | ||||
| 		<table border="0" width="100%"> | ||||
| 			<tr> | ||||
| 				<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> | ||||
| 				</td> | ||||
| 				<td align="center"> | ||||
| 					<h1>checked_delete.hpp</h1> | ||||
| 				</td> | ||||
| 			</tr> | ||||
| 			<tr> | ||||
| 				<td colspan="2" height="64"> </td> | ||||
| 			</tr> | ||||
| 		</table> | ||||
| 		<p> | ||||
| 			The header <STRONG><boost/checked_delete.hpp></STRONG> defines two  | ||||
| 			function templates, <STRONG>checked_delete</STRONG> and <STRONG>checked_array_delete</STRONG>,  | ||||
| 			and two class templates, <STRONG>checked_deleter</STRONG> and <STRONG>checked_array_deleter</STRONG>. | ||||
| 		</p> | ||||
| 		<P>The C++ Standard allows, in 5.3.5/5, pointers to incomplete class types to be  | ||||
| 			deleted with a <EM>delete-expression</EM>. When the class has a non-trivial  | ||||
| 			destructor, or a class-specific operator delete, the behavior is undefined.  | ||||
| 			Some compilers issue a warning when an incomplete type is deleted, but  | ||||
| 			unfortunately, not all do, and programmers sometimes ignore or disable  | ||||
| 			warnings.</P> | ||||
| 		<P>A particularly troublesome case is when a smart pointer's destructor, such as <STRONG> | ||||
| 				boost::scoped_ptr<T>::~scoped_ptr</STRONG>, is instantiated with an  | ||||
| 			incomplete type. This can often lead to silent, hard to track failures.</P> | ||||
| 		<P>The supplied function and class templates can be used to prevent these problems,  | ||||
| 			as they require a complete type, and cause a compilation error otherwise.</P> | ||||
| 		<h3><a name="Synopsis">Synopsis</a></h3> | ||||
| 		<pre> | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| template<class T> void checked_delete(T * p); | ||||
| template<class T> void checked_array_delete(T * p); | ||||
| template<class T> struct checked_deleter; | ||||
| template<class T> struct checked_array_deleter; | ||||
|  | ||||
| } | ||||
| </pre> | ||||
| 		<h3>checked_delete</h3> | ||||
| 		<h4><a name="checked_delete">template<class T> void checked_delete(T * p);</a></h4> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete p</tt> | ||||
| 				must be well-formed. | ||||
| 			</p> | ||||
| 			<p> | ||||
| 				<b>Effects:</b> <tt>delete p;</tt> | ||||
| 			</p> | ||||
| 		</blockquote> | ||||
| 		<h3>checked_array_delete</h3> | ||||
| 		<h4><a name="checked_array_delete">template<class T> void checked_array_delete(T  | ||||
| 				* p);</a></h4> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete [] p</tt> | ||||
| 				must be well-formed. | ||||
| 			</p> | ||||
| 			<p> | ||||
| 				<b>Effects:</b> <tt>delete [] p;</tt> | ||||
| 			</p> | ||||
| 		</blockquote> | ||||
| 		<h3>checked_deleter</h3> | ||||
| 		<pre> | ||||
| template<class T> struct checked_deleter | ||||
| { | ||||
|     typedef void result_type; | ||||
|     typedef T * argument_type; | ||||
|     void operator()(T * p) const; | ||||
| }; | ||||
| </pre> | ||||
| 		<h4>void checked_deleter<T>::operator()(T * p) const;</h4> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete p</tt> | ||||
| 				must be well-formed. | ||||
| 			</p> | ||||
| 			<p> | ||||
| 				<b>Effects:</b> <tt>delete p;</tt> | ||||
| 			</p> | ||||
| 		</blockquote> | ||||
| 		<h3>checked_array_deleter</h3> | ||||
| 		<pre> | ||||
| template<class T> struct checked_array_deleter | ||||
| { | ||||
|     typedef void result_type; | ||||
|     typedef T * argument_type; | ||||
|     void operator()(T * p) const; | ||||
| }; | ||||
| </pre> | ||||
| 		<h4>void checked_array_deleter<T>::operator()(T * p) const;</h4> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete [] p</tt> | ||||
| 				must be well-formed. | ||||
| 			</p> | ||||
| 			<p> | ||||
| 				<b>Effects:</b> <tt>delete [] p;</tt> | ||||
| 			</p> | ||||
| 		</blockquote> | ||||
| 		<h3><a name="Acknowledgements">Acknowledgements</a></h3> | ||||
| 		<p> | ||||
| 			The function templates <STRONG>checked_delete</STRONG> and <STRONG>checked_array_delete</STRONG> | ||||
| 			were originally part of <STRONG><boost/utility.hpp></STRONG>, and the  | ||||
| 			documentation acknowledged Beman Dawes, Dave Abrahams, Vladimir Prus, Rainer  | ||||
| 			Deyke, John Maddock, and others as contributors. | ||||
| 		</p> | ||||
| 		<p> | ||||
| 			<br> | ||||
| 			<small>Copyright <20> 2002 by Peter Dimov. Distributed under the Boost Software License, Version  | ||||
| 				1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or  | ||||
| 				copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> | ||||
| 	</body> | ||||
| </html> | ||||
							
								
								
									
										28
									
								
								checked_delete_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								checked_delete_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| //  Boost checked_delete test program  ---------------------------------------// | ||||
|  | ||||
| //  Copyright Beman Dawes 2001.  Distributed under the Boost | ||||
| //  Software License, Version 1.0. (See accompanying file | ||||
| //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org/libs/utility for documentation. | ||||
|  | ||||
| //  Revision History | ||||
| //  21 May 01  Initial version (Beman Dawes) | ||||
|  | ||||
| #include <boost/checked_delete.hpp>  // for checked_delete | ||||
|  | ||||
| //  This program demonstrates compiler errors when trying to delete an | ||||
| //  incomplete type. | ||||
|  | ||||
| namespace | ||||
| { | ||||
|     class Incomplete; | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     Incomplete * p = 0; | ||||
|     boost::checked_delete(p);          // should cause compile time error | ||||
|     boost::checked_array_delete(p);    // should cause compile time error | ||||
|     return 0; | ||||
| }   // main | ||||
| @@ -1,29 +1,19 @@ | ||||
| <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>Header <boost/compressed_pair.hpp></title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" | ||||
| vlink="#800080"> | ||||
|  | ||||
| <h2><img src="../../c++boost.gif" width="276" height="86">Header | ||||
| <<a href="../../boost/detail/call_traits.hpp">boost/compressed_pair.hpp</a>></h2> | ||||
|  | ||||
| <p>All of the contents of <boost/compressed_pair.hpp> are | ||||
| defined inside namespace boost.</p> | ||||
|  | ||||
| <p>The class compressed pair is very similar to std::pair, but if | ||||
| either of the template arguments are empty classes, then the | ||||
| "empty member optimisation" is applied to compress the | ||||
| size of the pair.</p> | ||||
|  | ||||
| <pre>template <class T1, class T2> | ||||
|    <head> | ||||
|       <title>Header </title> | ||||
|       <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 5.0"> | ||||
|       <boostcompressed_pair.hpp> | ||||
|    </head> | ||||
|    <body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#800080"> | ||||
|       <h2><img src="../../boost.png" width="276" height="86">Header <<a href="../../boost/detail/compressed_pair.hpp">boost/compressed_pair.hpp</a>></h2> | ||||
|       <p>All of the contents of <boost/compressed_pair.hpp> are defined inside  | ||||
|          namespace boost.</p> | ||||
|       <p>The class compressed pair is very similar to std::pair, but if either of the  | ||||
|          template arguments are empty classes, then the "empty base-class optimisation"  | ||||
|          is applied to compress the size of the pair.</p> | ||||
|       <pre>template <class T1, class T2> | ||||
| class compressed_pair | ||||
| { | ||||
| public: | ||||
| @@ -41,6 +31,8 @@ public: | ||||
| 	explicit compressed_pair(first_param_type x); | ||||
| 	explicit compressed_pair(second_param_type y); | ||||
|  | ||||
| 	compressed_pair& operator=(const compressed_pair&); | ||||
|  | ||||
| 	first_reference       first(); | ||||
| 	first_const_reference first() const; | ||||
|  | ||||
| @@ -49,44 +41,36 @@ public: | ||||
|  | ||||
| 	void swap(compressed_pair& y); | ||||
| };</pre> | ||||
|       <p>The two members of the pair can be accessed using the member functions first()  | ||||
|          and second(). Note that not all member functions can be instantiated for all  | ||||
|          template parameter types. In particular compressed_pair can be instantiated for  | ||||
|          reference and array types, however in these cases the range of constructors  | ||||
|          that can be used are limited. If types T1 and T2 are the same type, then there  | ||||
|          is only one version of the single-argument constructor, and this constructor  | ||||
|          initialises both values in the pair to the passed value.</p> | ||||
|       <P>Note that if either member is a POD type, then that member is not  | ||||
|          zero-initialized by the compressed_pair default constructor: it's up to you to  | ||||
|          supply an initial value for these types if you want them to have a default  | ||||
|          value.</P> | ||||
|       <p>Note that compressed_pair can not be instantiated if either of the template  | ||||
|          arguments is a union type, unless there is compiler support for  | ||||
|          boost::is_union, or if boost::is_union is specialised for the union type.</p> | ||||
|       <p>Finally, a word of caution for Visual C++ 6 users: if either argument is an  | ||||
|          empty type, then assigning to that member will produce memory corruption,  | ||||
|          unless the empty type has a "do nothing" assignment operator defined. This is  | ||||
|          due to a bug in the way VC6 generates implicit assignment operators.</p> | ||||
|       <h3>Acknowledgements</h3> | ||||
|       <p>Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and John  | ||||
|          Maddock.</p> | ||||
|       <p>Maintained by <a href="mailto:john@johnmaddock.co.uk">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.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p> | ||||
|       <hr> | ||||
|       <p>Revised | ||||
|       <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->07 November 2007<!--webbot bot="Timestamp" endspan i-checksum="40338" --></p> | ||||
|       <p><EFBFBD> Copyright Beman Dawes, 2000.</p> | ||||
| <p>Distributed under the Boost Software License, Version 1.0. See | ||||
| <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p> | ||||
|  | ||||
| <p>The two members of the pair can be accessed using the member | ||||
| functions first() and second(). Note that not all member | ||||
| functions can be instantiated for all template parameter types. | ||||
| In particular compressed_pair can be instantiated for reference | ||||
| and array types, however in these cases the range of constructors | ||||
| that can be used are limited. If types T1 and T2 are the same | ||||
| type, then there is only one version of the single-argument | ||||
| constructor, and this constructor initialises both values in the | ||||
| pair to the passed value.</p> | ||||
|  | ||||
| <p>Note that compressed_pair can not be instantiated if either of | ||||
| the template arguments is an enumerator type, unless there is | ||||
| compiler support for boost::is_enum, or if boost::is_enum is | ||||
| specialised for the enumerator type.</p> | ||||
|  | ||||
| <p>Finally, compressed_pair requires compiler support for partial | ||||
| specialisation of class templates - without that support | ||||
| compressed_pair behaves just like std::pair.</p> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <p>Revised 08 March 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> | ||||
| </body> | ||||
| </html> | ||||
|    </body> | ||||
| </html> | ||||
| @@ -1,9 +1,9 @@ | ||||
|  // boost::compressed_pair test program    | ||||
| //  boost::compressed_pair test program    | ||||
|      | ||||
|  //  (C) Copyright John Maddock 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.    | ||||
| //  (C) Copyright John Maddock 2000.  | ||||
| //  Use, modification and distribution are subject to the Boost Software License, | ||||
| //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt). | ||||
|  | ||||
| // standalone test program for <boost/compressed_pair.hpp> | ||||
| // Revised 03 Oct 2000:  | ||||
| @@ -14,27 +14,23 @@ | ||||
| #include <cassert> | ||||
|  | ||||
| #include <boost/compressed_pair.hpp> | ||||
| #include <boost/type_traits/type_traits_test.hpp> | ||||
| #include <boost/test/test_tools.hpp> | ||||
|  | ||||
| using namespace boost; | ||||
|  | ||||
| namespace boost { | ||||
| #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION | ||||
| template <> struct is_empty<empty_UDT> | ||||
| { static const bool value = true; }; | ||||
| template <> struct is_empty<empty_POD_UDT> | ||||
| { static const bool value = true; }; | ||||
| template <> struct is_POD<empty_POD_UDT> | ||||
| { static const bool value = true; }; | ||||
| #else | ||||
| template <> struct is_empty<empty_UDT> | ||||
| { enum{ value = true }; }; | ||||
| template <> struct is_empty<empty_POD_UDT> | ||||
| { enum{ value = true }; }; | ||||
| template <> struct is_POD<empty_POD_UDT> | ||||
| { enum{ value = true }; }; | ||||
| #endif | ||||
| } | ||||
| struct empty_UDT | ||||
| { | ||||
|    ~empty_UDT(){}; | ||||
|    empty_UDT& operator=(const empty_UDT&){ return *this; } | ||||
|    bool operator==(const empty_UDT&)const | ||||
|    { return true; } | ||||
| }; | ||||
| struct empty_POD_UDT | ||||
| { | ||||
|    empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; } | ||||
|    bool operator==(const empty_POD_UDT&)const | ||||
|    { return true; } | ||||
| }; | ||||
|  | ||||
| struct non_empty1 | ||||
| {  | ||||
| @@ -54,101 +50,346 @@ struct non_empty2 | ||||
|    { return a.i == b.i; } | ||||
| }; | ||||
|  | ||||
| int main(int argc, char *argv[ ]) | ||||
| { | ||||
|    compressed_pair<int, double> cp1(1, 1.3); | ||||
|    assert(cp1.first() == 1); | ||||
|    assert(cp1.second() == 1.3); | ||||
|    compressed_pair<int, double> cp1b(2, 2.3); | ||||
|    assert(cp1b.first() == 2); | ||||
|    assert(cp1b.second() == 2.3); | ||||
|    swap(cp1, cp1b); | ||||
|    assert(cp1b.first() == 1); | ||||
|    assert(cp1b.second() == 1.3); | ||||
|    assert(cp1.first() == 2); | ||||
|    assert(cp1.second() == 2.3); | ||||
|    compressed_pair<non_empty1, non_empty2> cp1c(non_empty1(9)); | ||||
|    assert(cp1c.second() == non_empty2()); | ||||
|    assert(cp1c.first() == non_empty1(9)); | ||||
|    compressed_pair<non_empty1, non_empty2> cp1d(non_empty2(9)); | ||||
|    assert(cp1d.second() == non_empty2(9)); | ||||
|    assert(cp1d.first() == non_empty1()); | ||||
|  | ||||
|    compressed_pair<int, double> cp1e(cp1); | ||||
|  | ||||
|    compressed_pair<empty_UDT, int> cp2(2); | ||||
|    assert(cp2.second() == 2); | ||||
|    compressed_pair<int, empty_UDT> cp3(1); | ||||
|    assert(cp3.first() ==1); | ||||
|    compressed_pair<empty_UDT, empty_UDT> cp4; | ||||
|    compressed_pair<empty_UDT, empty_POD_UDT> cp5; | ||||
|    compressed_pair<int, empty_UDT> cp9(empty_UDT()); | ||||
|    compressed_pair<int, empty_UDT> cp10(1); | ||||
|    assert(cp10.first() == 1); | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) | ||||
|    int i = 0; | ||||
|    compressed_pair<int&, int&> cp6(i,i); | ||||
|    assert(cp6.first() == i); | ||||
|    assert(cp6.second() == i); | ||||
|    assert(&cp6.first() == &i); | ||||
|    assert(&cp6.second() == &i); | ||||
|    compressed_pair<int, double[2]> cp7; | ||||
|    cp7.first(); | ||||
|    double* pd = cp7.second(); | ||||
| #ifdef __GNUC__ | ||||
| using std::swap; | ||||
| #endif | ||||
|    soft_value_test(true, (sizeof(compressed_pair<empty_UDT, int>) < sizeof(std::pair<empty_UDT, int>))) | ||||
|    soft_value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>))) | ||||
|    soft_value_test(true, (sizeof(compressed_pair<empty_UDT, empty_UDT>) < sizeof(std::pair<empty_UDT, empty_UDT>))) | ||||
|    soft_value_test(true, (sizeof(compressed_pair<empty_UDT, empty_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>))) | ||||
|    soft_value_test(true, (sizeof(compressed_pair<empty_UDT, compressed_pair<empty_POD_UDT, int> >) < sizeof(std::pair<empty_UDT, std::pair<empty_POD_UDT, int> >))) | ||||
|  | ||||
|    return check_result(argc, argv); | ||||
| template <class T1, class T2> | ||||
| struct compressed_pair_tester | ||||
| { | ||||
|    // define the types we need: | ||||
|    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; | ||||
|    // define our test proc: | ||||
|    static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); | ||||
| }; | ||||
|  | ||||
| template <class T1, class T2> | ||||
| void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4) | ||||
| { | ||||
| #ifndef __GNUC__ | ||||
|    // gcc 2.90 can't cope with function scope using | ||||
|    // declarations, and generates an internal compiler error... | ||||
|    using std::swap; | ||||
| #endif | ||||
|    // default construct: | ||||
|    boost::compressed_pair<T1,T2> cp1; | ||||
|    // first param construct: | ||||
|    boost::compressed_pair<T1,T2> cp2(p1); | ||||
|    cp2.second() = p2; | ||||
|    BOOST_CHECK(cp2.first() == p1); | ||||
|    BOOST_CHECK(cp2.second() == p2); | ||||
|    // second param construct: | ||||
|    boost::compressed_pair<T1,T2> cp3(p2); | ||||
|    cp3.first() = p1; | ||||
|    BOOST_CHECK(cp3.second() == p2); | ||||
|    BOOST_CHECK(cp3.first() == p1); | ||||
|    // both param construct: | ||||
|    boost::compressed_pair<T1,T2> cp4(p1, p2); | ||||
|    BOOST_CHECK(cp4.first() == p1); | ||||
|    BOOST_CHECK(cp4.second() == p2); | ||||
|    boost::compressed_pair<T1,T2> cp5(p3, p4); | ||||
|    BOOST_CHECK(cp5.first() == p3); | ||||
|    BOOST_CHECK(cp5.second() == p4); | ||||
|    // check const members: | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp4; | ||||
|    BOOST_CHECK(cpr1.first() == p1); | ||||
|    BOOST_CHECK(cpr1.second() == p2); | ||||
|  | ||||
|    // copy construct: | ||||
|    boost::compressed_pair<T1,T2> cp6(cp4); | ||||
|    BOOST_CHECK(cp6.first() == p1); | ||||
|    BOOST_CHECK(cp6.second() == p2); | ||||
|    // assignment: | ||||
|    cp1 = cp4; | ||||
|    BOOST_CHECK(cp1.first() == p1); | ||||
|    BOOST_CHECK(cp1.second() == p2); | ||||
|    cp1 = cp5; | ||||
|    BOOST_CHECK(cp1.first() == p3); | ||||
|    BOOST_CHECK(cp1.second() == p4); | ||||
|    // swap: | ||||
|    cp4.swap(cp5); | ||||
|    BOOST_CHECK(cp4.first() == p3); | ||||
|    BOOST_CHECK(cp4.second() == p4); | ||||
|    BOOST_CHECK(cp5.first() == p1); | ||||
|    BOOST_CHECK(cp5.second() == p2); | ||||
|    swap(cp4,cp5); | ||||
|    BOOST_CHECK(cp4.first() == p1); | ||||
|    BOOST_CHECK(cp4.second() == p2); | ||||
|    BOOST_CHECK(cp5.first() == p3); | ||||
|    BOOST_CHECK(cp5.second() == p4); | ||||
| } | ||||
|  | ||||
| // | ||||
| // instanciate some compressed pairs: | ||||
| #ifdef __MWERKS__ | ||||
| template class compressed_pair<int, double>; | ||||
| template class compressed_pair<int, int>; | ||||
| template class compressed_pair<empty_UDT, int>; | ||||
| template class compressed_pair<int, empty_UDT>; | ||||
| template class compressed_pair<empty_UDT, empty_UDT>; | ||||
| template class compressed_pair<empty_UDT, empty_POD_UDT>; | ||||
| #else | ||||
| template class boost::compressed_pair<int, double>; | ||||
| template class boost::compressed_pair<int, int>; | ||||
| template class boost::compressed_pair<empty_UDT, int>; | ||||
| template class boost::compressed_pair<int, empty_UDT>; | ||||
| template class boost::compressed_pair<empty_UDT, empty_UDT>; | ||||
| template class boost::compressed_pair<empty_UDT, empty_POD_UDT>; | ||||
| #endif | ||||
| // tests for case where one or both  | ||||
| // parameters are reference types: | ||||
| // | ||||
| template <class T1, class T2> | ||||
| struct compressed_pair_reference_tester | ||||
| { | ||||
|    // define the types we need: | ||||
|    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; | ||||
|    // define our test proc: | ||||
|    static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); | ||||
| }; | ||||
|  | ||||
| template <class T1, class T2> | ||||
| void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4) | ||||
| { | ||||
| #ifndef __GNUC__ | ||||
|    // gcc 2.90 can't cope with function scope using | ||||
|    // declarations, and generates an internal compiler error... | ||||
|    using std::swap; | ||||
| #endif | ||||
|    // both param construct: | ||||
|    boost::compressed_pair<T1,T2> cp4(p1, p2); | ||||
|    BOOST_CHECK(cp4.first() == p1); | ||||
|    BOOST_CHECK(cp4.second() == p2); | ||||
|    boost::compressed_pair<T1,T2> cp5(p3, p4); | ||||
|    BOOST_CHECK(cp5.first() == p3); | ||||
|    BOOST_CHECK(cp5.second() == p4); | ||||
|    // check const members: | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp4; | ||||
|    BOOST_CHECK(cpr1.first() == p1); | ||||
|    BOOST_CHECK(cpr1.second() == p2); | ||||
|  | ||||
|    // copy construct: | ||||
|    boost::compressed_pair<T1,T2> cp6(cp4); | ||||
|    BOOST_CHECK(cp6.first() == p1); | ||||
|    BOOST_CHECK(cp6.second() == p2); | ||||
|    // assignment: | ||||
|    // VC6 bug: | ||||
|    // When second() is an empty class, VC6 performs the | ||||
|    // assignment by doing a memcpy - even though the empty | ||||
|    // class is really a zero sized base class, the result | ||||
|    // is that the memory of first() gets trampled over. | ||||
|    // Similar arguments apply to the case that first() is  | ||||
|    // an empty base class. | ||||
|    // Strangely the problem is dependent upon the compiler | ||||
|    // settings - some generate the problem others do not. | ||||
|    cp4.first() = p3; | ||||
|    cp4.second() = p4; | ||||
|    BOOST_CHECK(cp4.first() == p3); | ||||
|    BOOST_CHECK(cp4.second() == p4); | ||||
| } | ||||
| // | ||||
| // supplimentary tests for case where first arg only is a reference type: | ||||
| // | ||||
| template <class T1, class T2> | ||||
| struct compressed_pair_reference1_tester | ||||
| { | ||||
|    // define the types we need: | ||||
|    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; | ||||
|    // define our test proc: | ||||
|    static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); | ||||
| }; | ||||
|  | ||||
| template <class T1, class T2> | ||||
| void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) | ||||
| { | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
| #ifndef __MWERKS__ | ||||
|    // first param construct: | ||||
|    boost::compressed_pair<T1,T2> cp2(p1); | ||||
|    cp2.second() = p2; | ||||
|    BOOST_CHECK(cp2.first() == p1); | ||||
|    BOOST_CHECK(cp2.second() == p2); | ||||
| #endif | ||||
| } | ||||
| // | ||||
| // now some for which only a few specific members can be instantiated, | ||||
| // first references: | ||||
| template double& compressed_pair<double, int&>::first(); | ||||
| template int& compressed_pair<double, int&>::second(); | ||||
| #if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)) | ||||
| template compressed_pair<double, int&>::compressed_pair(int&); | ||||
| #endif | ||||
| template compressed_pair<double, int&>::compressed_pair(call_traits<double>::param_type,int&); | ||||
| // supplimentary tests for case where second arg only is a reference type: | ||||
| // | ||||
| // and then arrays: | ||||
| #ifndef __BORLANDC__ | ||||
| template call_traits<int[2]>::reference compressed_pair<double, int[2]>::second(); | ||||
| template <class T1, class T2> | ||||
| struct compressed_pair_reference2_tester | ||||
| { | ||||
|    // define the types we need: | ||||
|    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; | ||||
|    // define our test proc: | ||||
|    static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); | ||||
| }; | ||||
|  | ||||
| template <class T1, class T2> | ||||
| void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) | ||||
| { | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|    // second param construct: | ||||
|    boost::compressed_pair<T1,T2> cp3(p2); | ||||
|    cp3.first() = p1; | ||||
|    BOOST_CHECK(cp3.second() == p2); | ||||
|    BOOST_CHECK(cp3.first() == p1); | ||||
| #endif | ||||
| template call_traits<double>::reference compressed_pair<double, int[2]>::first(); | ||||
| #if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)) | ||||
| template compressed_pair<double, int[2]>::compressed_pair(call_traits<double>::param_type); | ||||
| #endif | ||||
| template compressed_pair<double, int[2]>::compressed_pair(); | ||||
| #endif // __MWERKS__ | ||||
| #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
| } | ||||
|  | ||||
| // | ||||
| // tests for where one or the other parameter is an array: | ||||
| // | ||||
| template <class T1, class T2> | ||||
| struct compressed_pair_array1_tester | ||||
| { | ||||
|    // define the types we need: | ||||
|    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; | ||||
|    // define our test proc: | ||||
|    static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); | ||||
| }; | ||||
|  | ||||
| template <class T1, class T2> | ||||
| void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) | ||||
| { | ||||
|   // default construct: | ||||
|    boost::compressed_pair<T1,T2> cp1; | ||||
|    // second param construct: | ||||
|    boost::compressed_pair<T1,T2> cp3(p2); | ||||
|    cp3.first()[0] = p1[0]; | ||||
|    BOOST_CHECK(cp3.second() == p2); | ||||
|    BOOST_CHECK(cp3.first()[0] == p1[0]); | ||||
|    // check const members: | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp3; | ||||
|    BOOST_CHECK(cpr1.first()[0] == p1[0]); | ||||
|    BOOST_CHECK(cpr1.second() == p2); | ||||
|  | ||||
|    BOOST_CHECK(sizeof(T1) == sizeof(cp1.first())); | ||||
| } | ||||
|  | ||||
| template <class T1, class T2> | ||||
| struct compressed_pair_array2_tester | ||||
| { | ||||
|    // define the types we need: | ||||
|    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; | ||||
|    // define our test proc: | ||||
|    static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); | ||||
| }; | ||||
|  | ||||
| template <class T1, class T2> | ||||
| void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) | ||||
| { | ||||
|    // default construct: | ||||
|    boost::compressed_pair<T1,T2> cp1; | ||||
|    // first param construct: | ||||
|    boost::compressed_pair<T1,T2> cp2(p1); | ||||
|    cp2.second()[0] = p2[0]; | ||||
|    BOOST_CHECK(cp2.first() == p1); | ||||
|    BOOST_CHECK(cp2.second()[0] == p2[0]); | ||||
|    // check const members: | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp2; | ||||
|    BOOST_CHECK(cpr1.first() == p1); | ||||
|    BOOST_CHECK(cpr1.second()[0] == p2[0]); | ||||
|  | ||||
|    BOOST_CHECK(sizeof(T2) == sizeof(cp1.second())); | ||||
| } | ||||
|  | ||||
| template <class T1, class T2> | ||||
| struct compressed_pair_array_tester | ||||
| { | ||||
|    // define the types we need: | ||||
|    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; | ||||
|    // define our test proc: | ||||
|    static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4); | ||||
| }; | ||||
|  | ||||
| template <class T1, class T2> | ||||
| void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type) | ||||
| { | ||||
|    // default construct: | ||||
|    boost::compressed_pair<T1,T2> cp1; | ||||
|    cp1.first()[0] = p1[0]; | ||||
|    cp1.second()[0] = p2[0]; | ||||
|    BOOST_CHECK(cp1.first()[0] == p1[0]); | ||||
|    BOOST_CHECK(cp1.second()[0] == p2[0]); | ||||
|    // check const members: | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp1; | ||||
|    BOOST_CHECK(cpr1.first()[0] == p1[0]); | ||||
|    BOOST_CHECK(cpr1.second()[0] == p2[0]); | ||||
|  | ||||
|    BOOST_CHECK(sizeof(T1) == sizeof(cp1.first())); | ||||
|    BOOST_CHECK(sizeof(T2) == sizeof(cp1.second())); | ||||
| } | ||||
|  | ||||
| int test_main(int, char *[]) | ||||
| { | ||||
|    // declare some variables to pass to the tester: | ||||
|    non_empty1 ne1(2); | ||||
|    non_empty1 ne2(3); | ||||
|    non_empty2 ne3(4); | ||||
|    non_empty2 ne4(5); | ||||
|    empty_POD_UDT  e1; | ||||
|    empty_UDT      e2; | ||||
|  | ||||
|    // T1 != T2, both non-empty | ||||
|    compressed_pair_tester<non_empty1,non_empty2>::test(ne1, ne3, ne2, ne4); | ||||
|    // T1 != T2, T2 empty | ||||
|    compressed_pair_tester<non_empty1,empty_POD_UDT>::test(ne1, e1, ne2, e1); | ||||
|    // T1 != T2, T1 empty | ||||
|    compressed_pair_tester<empty_POD_UDT,non_empty2>::test(e1, ne3, e1, ne4); | ||||
|    // T1 != T2, both empty | ||||
|    compressed_pair_tester<empty_POD_UDT,empty_UDT>::test(e1, e2, e1, e2); | ||||
|    // T1 == T2, both non-empty | ||||
|    compressed_pair_tester<non_empty1,non_empty1>::test(ne1, ne1, ne2, ne2); | ||||
|    // T1 == T2, both empty | ||||
|    compressed_pair_tester<empty_UDT,empty_UDT>::test(e2, e2, e2, e2); | ||||
|  | ||||
|  | ||||
|    // test references: | ||||
|  | ||||
|    // T1 != T2, both non-empty | ||||
|    compressed_pair_reference_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4); | ||||
|    compressed_pair_reference_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4); | ||||
|    compressed_pair_reference1_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4); | ||||
|    compressed_pair_reference2_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4); | ||||
|    // T1 != T2, T2 empty | ||||
|    compressed_pair_reference_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1); | ||||
|    compressed_pair_reference1_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1); | ||||
|    // T1 != T2, T1 empty | ||||
|    compressed_pair_reference_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4); | ||||
|    compressed_pair_reference2_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4); | ||||
|    // T1 == T2, both non-empty | ||||
|    compressed_pair_reference_tester<non_empty1&,non_empty1&>::test(ne1, ne1, ne2, ne2); | ||||
|  | ||||
|    // tests arrays: | ||||
|    non_empty1 nea1[2]; | ||||
|    non_empty1 nea2[2]; | ||||
|    non_empty2 nea3[2]; | ||||
|    non_empty2 nea4[2]; | ||||
|    nea1[0] = non_empty1(5); | ||||
|    nea2[0] = non_empty1(6); | ||||
|    nea3[0] = non_empty2(7); | ||||
|    nea4[0] = non_empty2(8); | ||||
|     | ||||
|    // T1 != T2, both non-empty | ||||
|    compressed_pair_array1_tester<non_empty1[2],non_empty2>::test(nea1, ne3, nea2, ne4); | ||||
|    compressed_pair_array2_tester<non_empty1,non_empty2[2]>::test(ne1, nea3, ne2, nea4); | ||||
|    compressed_pair_array_tester<non_empty1[2],non_empty2[2]>::test(nea1, nea3, nea2, nea4); | ||||
|    // T1 != T2, T2 empty | ||||
|    compressed_pair_array1_tester<non_empty1[2],empty_POD_UDT>::test(nea1, e1, nea2, e1); | ||||
|    // T1 != T2, T1 empty | ||||
|    compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4); | ||||
|    // T1 == T2, both non-empty | ||||
|    compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2); | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| unsigned int expected_failures = 0; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,325 +0,0 @@ | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
| <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> | ||||
| <meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
| <title>Counting Iterator Adaptor Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|  | ||||
| <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" | ||||
| align="center" width="277" height="86"> | ||||
|  | ||||
| <h1>Counting Iterator Adaptor</h1> | ||||
|  | ||||
| Defined in header | ||||
| <a href="../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a> | ||||
|  | ||||
| <p> | ||||
| How would you fill up a vector with the numbers zero | ||||
| through one hundred using <a | ||||
| href="http://www.sgi.com/tech/stl/copy.html"><tt>std::copy()</tt></a>? The | ||||
| only iterator operation missing from builtin integer types is an | ||||
| <tt>operator*()</tt> that returns the current | ||||
| value of the integer.  The counting iterator adaptor adds this crucial piece of | ||||
| functionality to whatever type it wraps. One can use the | ||||
| counting iterator adaptor not only with integer types, but with any | ||||
| type that is <tt>Incrementable</tt> (see type requirements <a href="#requirements">below</a>).  The | ||||
| following <b>pseudo-code</b> shows the general idea of how the | ||||
| counting iterator is implemented. | ||||
| </p> | ||||
|  | ||||
| <pre> | ||||
|   // inside a hypothetical counting_iterator class... | ||||
|   typedef Incrementable value_type; | ||||
|   value_type counting_iterator::operator*() const { | ||||
|     return this->base; // no dereference! | ||||
|   } | ||||
| </pre> | ||||
|  | ||||
| All of the other operators of the counting iterator behave in the same | ||||
| fashion as the <tt>Incrementable</tt> base type. | ||||
|  | ||||
| <h2>Synopsis</h2> | ||||
|  | ||||
| <pre> | ||||
| namespace boost { | ||||
|   template <class Incrementable> | ||||
|   struct <a href="#counting_iterator_traits">counting_iterator_traits</a>; | ||||
|  | ||||
|   template <class Incrementable> | ||||
|   struct <a href="#counting_iterator_generator">counting_iterator_generator</a>; | ||||
|  | ||||
|   template <class Incrementable> | ||||
|   typename counting_iterator_generator<Incrementable>::type | ||||
|   <a href="#make_counting_iterator">make_counting_iterator</a>(Incrementable x); | ||||
| } | ||||
| </pre> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <h2><a name="counting_iterator_generator">The Counting Iterator Type | ||||
| Generator</a></h2> | ||||
|  | ||||
| The class template <tt>counting_iterator_generator<Incrementable></tt> is a <a href="../../more/generic_programming.html#type_generator">type generator</a> for counting iterators. | ||||
|  | ||||
| <pre> | ||||
| template <class Incrementable> | ||||
| class counting_iterator_generator | ||||
| { | ||||
| public: | ||||
|     typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type; | ||||
| }; | ||||
| </pre> | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| In this example we use the counting iterator generator to create a | ||||
| counting iterator, and count from zero to four. | ||||
|  | ||||
| <pre> | ||||
| #include <boost/config.hpp> | ||||
| #include <iostream> | ||||
| #include <boost/counting_iterator.hpp> | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   // Example of using counting_iterator_generator | ||||
|   std::cout << "counting from 0 to 4:" << std::endl; | ||||
|   boost::counting_iterator_generator<int>::type first(0), last(4); | ||||
|   std::copy(first, last, std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // to be continued... | ||||
| </pre> | ||||
| The output from this part is: | ||||
| <pre> | ||||
| counting from 0 to 4: | ||||
| 0 1 2 3  | ||||
| </pre> | ||||
|  | ||||
| <h3>Template Parameters</h3> | ||||
|  | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH>Parameter</TH><TH>Description</TH> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>Incrementable</tt></TD> | ||||
| <TD>The type being wrapped by the adaptor.</TD> | ||||
| </TR> | ||||
|  | ||||
| </Table> | ||||
|  | ||||
| <h3>Model of</h3> | ||||
|  | ||||
| If the <tt>Incrementable</tt> type has all of the functionality of a | ||||
| <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
| Access Iterator</a> except the <tt>operator*()</tt>, then the counting | ||||
| iterator will be a model of <a | ||||
| href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
| Access Iterator</a>. If the <tt>Incrementable</tt> type has less | ||||
| functionality, then the counting iterator will have correspondingly | ||||
| less functionality. | ||||
|  | ||||
| <h3><a name="requirements">Type Requirements</a></h3> | ||||
|  | ||||
| The <tt>Incrementable</tt> type must be <a | ||||
| href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default | ||||
| Constructible</a>, <a href="./CopyConstructible.html">Copy | ||||
| Constructible</a>, and <a href="./Assignable.html">Assignable</a>. | ||||
| Also, the <tt>Incrementable</tt> type must provide access to an | ||||
| associated <tt>difference_type</tt> and <tt>iterator_category</tt> | ||||
| through the <a | ||||
| href="#counting_iterator_traits"><tt>counting_iterator_traits</tt></a> | ||||
| class. | ||||
|  | ||||
| <p> | ||||
| Furthermore, if you wish to create a counting iterator that is a <a | ||||
| href="http://www.sgi.com/tech/stl/ForwardIterator.html"> Forward | ||||
| Iterator</a>, then the following expressions must be valid: | ||||
| <pre> | ||||
| Incrementable i, j; | ||||
| ++i         // pre-increment | ||||
| i == j      // operator equal | ||||
| </pre> | ||||
| If you wish to create a counting iterator that is a <a | ||||
| href="http://www.sgi.com/tech/stl/BidirectionalIterator.html"> | ||||
| Bidirectional Iterator</a>, then pre-decrement is also required: | ||||
| <pre> | ||||
| --i | ||||
| </pre> | ||||
| If you wish to create a counting iterator that is a <a | ||||
| href="http://www.sgi.com/tech/stl/RandomAccessIterator.html"> Random | ||||
| Access Iterator</a>, then these additional expressions are also required: | ||||
| <pre> | ||||
| <a href="#counting_iterator_traits">counting_iterator_traits</a><Incrementable>::difference_type n; | ||||
| i += n | ||||
| n = i - j | ||||
| i < j | ||||
| </pre> | ||||
|  | ||||
|  | ||||
|  | ||||
| <h3>Members</h3> | ||||
|  | ||||
| The counting iterator type implements the member functions and | ||||
| operators required of the <a | ||||
| href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
| Access Iterator</a> concept. In addition it has the following | ||||
| constructor: | ||||
|  | ||||
| <pre> | ||||
| counting_iterator_generator::type(const Incrementable& i) | ||||
| </pre> | ||||
|  | ||||
| <p> | ||||
| <hr> | ||||
| <p> | ||||
|  | ||||
|  | ||||
| <h2><a name="make_counting_iterator">The Counting Iterator Object Generator</a></h2> | ||||
|  | ||||
| <pre> | ||||
| template <class Incrementable> | ||||
| typename counting_iterator_generator<Incrementable>::type | ||||
| make_counting_iterator(Incrementable base); | ||||
| </pre> | ||||
|  | ||||
| An <a href="../../more/generic_programming.html#object_generator">object | ||||
| generator</a> function that provides a convenient way to create counting | ||||
| iterators.<p> | ||||
|  | ||||
|  | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| In this example we count from negative five to positive five, this | ||||
| time using the <tt>make_counting_iterator()</tt> function to save some | ||||
| typing. | ||||
|  | ||||
| <pre> | ||||
|   // continuing from previous example... | ||||
|  | ||||
|   std::cout << "counting from -5 to 4:" << std::endl; | ||||
|   std::copy(boost::make_counting_iterator(-5), | ||||
| 	    boost::make_counting_iterator(5), | ||||
| 	    std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // to be continued... | ||||
| </pre> | ||||
| The output from this part is: | ||||
| <pre> | ||||
| counting from -5 to 4: | ||||
| -5 -4 -3 -2 -1 0 1 2 3 4  | ||||
| </pre> | ||||
|  | ||||
| In the next example we create an array of numbers, and then create a | ||||
| second array of pointers, where each pointer is the address of a | ||||
| number in the first array. The counting iterator makes it easy to do | ||||
| this since dereferencing a counting iterator that is wrapping an | ||||
| iterator over the array of numbers just returns a pointer to the | ||||
| current location in the array. We then use the <a | ||||
| href="./indirect_iterator.htm">indirect iterator adaptor</a> to print | ||||
| out the number in the array by accessing the numbers through the array | ||||
| of pointers. | ||||
|  | ||||
| <pre> | ||||
|   // continuing from previous example... | ||||
|  | ||||
|   const int N = 7; | ||||
|   std::vector<int> numbers; | ||||
|   // Fill "numbers" array with [0,N) | ||||
|   std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N), | ||||
| 	    std::back_inserter(numbers)); | ||||
|  | ||||
|   std::vector<std::vector<int>::iterator> pointers; | ||||
|  | ||||
|   // Use counting iterator to fill in the array of pointers. | ||||
|   std::copy(boost::make_counting_iterator(numbers.begin()), | ||||
| 	    boost::make_counting_iterator(numbers.end()), | ||||
| 	    std::back_inserter(pointers)); | ||||
|  | ||||
|   // Use indirect iterator to print out numbers by accessing | ||||
|   // them through the array of pointers. | ||||
|   std::cout << "indirectly printing out the numbers from 0 to "  | ||||
| 	    << N << std::endl; | ||||
|   std::copy(boost::make_indirect_iterator(pointers.begin()), | ||||
| 	    boost::make_indirect_iterator(pointers.end()), | ||||
| 	    std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
| </pre> | ||||
| The output is: | ||||
| <pre> | ||||
| indirectly printing out the numbers from 0 to 7 | ||||
| 0 1 2 3 4 5 6  | ||||
| </pre> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <h2><a name="counting_iterator_traits">Counting Iterator Traits</a></h2> | ||||
|  | ||||
| The counting iterator adaptor needs to determine the appropriate | ||||
| <tt>difference_type</tt> and <tt>iterator_category</tt> to use based on the | ||||
| <tt>Incrementable</tt> type supplied by the user.  The | ||||
| <tt>counting_iterator_traits</tt> class provides these types.  If the | ||||
| <tt>Incrementable</tt> type is an integral type or an iterator, these types | ||||
| will be correctly deduced by the <tt>counting_iterator_traits</tt> provided by | ||||
| the library. Otherwise, the user must specialize | ||||
| <tt>counting_iterator_traits</tt> for her type or add nested typedefs to | ||||
| her type to fulfill the needs of | ||||
| <a href="http://www.sgi.com/tech/stl/iterator_traits.html"> | ||||
| <tt>std::iterator_traits</tt></a>. | ||||
|  | ||||
| <p>The following pseudocode describes how the <tt>counting_iterator_traits</tt> are determined: | ||||
|  | ||||
| <pre> | ||||
| template <class Incrementable> | ||||
| struct counting_iterator_traits | ||||
| { | ||||
|   if (numeric_limits<Incrementable>::is_specialized) { | ||||
|     if (!numeric_limits<Incrementable>::is_integer) | ||||
|        COMPILE_TIME_ERROR; | ||||
|  | ||||
|     if (!numeric_limits<Incrementable>::is_bounded | ||||
|         && numeric_limits<Incrementable>::is_signed) { | ||||
|         typedef Incrementable difference_type; | ||||
|     } | ||||
|     else if (numeric_limits<Incrementable>::is_integral) { | ||||
|         typedef <i>next-larger-signed-type-or-intmax_t</i> difference_type; | ||||
|     } | ||||
|     typedef std::random_access_iterator_tag iterator_category;    | ||||
|   } else { | ||||
|     typedef std::iterator_traits<Incrementable>::difference_type difference_type; | ||||
|     typedef std::iterator_traits<Incrementable>::iterator_category iterator_category; | ||||
|   } | ||||
| }; | ||||
| </pre> | ||||
|  | ||||
| <p>The italicized sections above are implementation details, but it is important | ||||
| to know that the <tt>difference_type</tt> for integral types is selected so that | ||||
| it can always represent the difference between two values if such a built-in | ||||
| integer exists. On platforms with a working <tt>std::numeric_limits</tt> | ||||
| implementation, the <tt>difference_type</tt> for any variable-length signed | ||||
| integer type <tt>T</tt> is <tt>T</tt> itself. | ||||
|  | ||||
| <hr> | ||||
| <p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" --></p> | ||||
| <p><EFBFBD> Copyright Jeremy Siek 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> | ||||
|  | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
| <!--  LocalWords:  html charset alt gif hpp incrementable const namespace htm | ||||
|  --> | ||||
| <!--  LocalWords:  struct  typename iostream int Siek CopyConstructible pre | ||||
|  --> | ||||
|  | ||||
| @@ -1,53 +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 <iostream> | ||||
| #include <iterator> | ||||
| #include <vector> | ||||
| #include <boost/counting_iterator.hpp> | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   // Example of using counting_iterator_generator | ||||
|   std::cout << "counting from 0 to 4:" << std::endl; | ||||
|   boost::counting_iterator_generator<int>::type first(0), last(4); | ||||
|   std::copy(first, last, std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // Example of using make_counting_iterator() | ||||
|   std::cout << "counting from -5 to 4:" << std::endl; | ||||
|   std::copy(boost::make_counting_iterator(-5), | ||||
| 	    boost::make_counting_iterator(5), | ||||
| 	    std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // Example of using counting iterator to create an array of pointers. | ||||
|   const int N = 7; | ||||
|   std::vector<int> numbers; | ||||
|   // Fill "numbers" array with [0,N) | ||||
|   std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N), | ||||
| 	    std::back_inserter(numbers)); | ||||
|  | ||||
|   std::vector<std::vector<int>::iterator> pointers; | ||||
|  | ||||
|   // Use counting iterator to fill in the array of pointers. | ||||
|   std::copy(boost::make_counting_iterator(numbers.begin()), | ||||
| 	    boost::make_counting_iterator(numbers.end()), | ||||
| 	    std::back_inserter(pointers)); | ||||
|  | ||||
|   // Use indirect iterator to print out numbers by accessing | ||||
|   // them through the array of pointers. | ||||
|   std::cout << "indirectly printing out the numbers from 0 to "  | ||||
| 	    << N << std::endl; | ||||
|   std::copy(boost::make_indirect_iterator(pointers.begin()), | ||||
| 	    boost::make_indirect_iterator(pointers.end()), | ||||
| 	    std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|    | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,263 +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 | ||||
| // 16 Feb 2001  Added a missing const. Made the tests run (somewhat) with | ||||
| //              plain MSVC again. (David Abrahams) | ||||
| // 11 Feb 2001  #if 0'd out use of counting_iterator on non-numeric types in | ||||
| //              MSVC without STLport, so that the other tests may proceed | ||||
| //              (David Abrahams) | ||||
| // 04 Feb 2001  Added use of iterator_tests.hpp (David Abrahams) | ||||
| // 28 Jan 2001  Removed not_an_iterator detritus (David Abrahams) | ||||
| // 24 Jan 2001  Initial revision (David Abrahams) | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #ifdef BOOST_MSVC | ||||
| # pragma warning(disable:4786) // identifier truncated in debug info | ||||
| #endif | ||||
|  | ||||
| #include <boost/pending/iterator_tests.hpp> | ||||
| #include <boost/counting_iterator.hpp> | ||||
| #include <boost/detail/iterator.hpp> | ||||
| #include <iostream> | ||||
| #include <climits> | ||||
| #include <iterator> | ||||
| #include <stdlib.h> | ||||
| #include <boost/utility.hpp> | ||||
| #include <vector> | ||||
| #include <list> | ||||
| #include <cassert> | ||||
| #ifndef BOOST_NO_LIMITS | ||||
| # include <limits> | ||||
| #endif | ||||
| #ifndef BOOST_NO_SLIST | ||||
| # include <slist> | ||||
| #endif | ||||
|  | ||||
| template <class T> struct is_numeric | ||||
| { | ||||
|     enum { value =  | ||||
| #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS | ||||
|         std::numeric_limits<T>::is_specialized | ||||
| #else | ||||
|         // Causes warnings with GCC, but how else can I detect numeric types at | ||||
|         // compile-time? | ||||
|         (boost::is_convertible<int,T>::value && | ||||
|          boost::is_convertible<T,int>::value) | ||||
| #endif | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| // Special tests for RandomAccess CountingIterators. | ||||
| template <class CountingIterator> | ||||
| void category_test( | ||||
|     CountingIterator start, | ||||
|     CountingIterator finish, | ||||
|     std::random_access_iterator_tag) | ||||
| { | ||||
|     typedef typename | ||||
|         boost::detail::iterator_traits<CountingIterator>::difference_type | ||||
|         difference_type; | ||||
|     difference_type distance = boost::detail::distance(start, finish); | ||||
|  | ||||
|     // Pick a random position internal to the range | ||||
|     difference_type offset = (unsigned)rand() % distance; | ||||
|     assert(offset >= 0); | ||||
|     CountingIterator internal = start; | ||||
|     std::advance(internal, offset); | ||||
|  | ||||
|     // Try some binary searches on the range to show that it's ordered | ||||
|     assert(std::binary_search(start, finish, *internal)); | ||||
|     CountingIterator x,y; | ||||
|     boost::tie(x,y) = std::equal_range(start, finish, *internal); | ||||
|     assert(boost::detail::distance(x, y) == 1); | ||||
|  | ||||
|     // Show that values outside the range can't be found | ||||
|     assert(!std::binary_search(start, boost::prior(finish), *finish)); | ||||
|  | ||||
|     // Do the generic random_access_iterator_test | ||||
|     typedef typename CountingIterator::value_type value_type; | ||||
|     std::vector<value_type> v; | ||||
|     for (value_type z = *start; z != *finish; ++z) | ||||
|         v.push_back(z); | ||||
|     if (v.size() >= 2) | ||||
|     { | ||||
|         // Note that this test requires a that the first argument is | ||||
|         // dereferenceable /and/ a valid iterator prior to the first argument | ||||
|         boost::random_access_iterator_test(start + 1, v.size() - 1, v.begin() + 1); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Special tests for bidirectional CountingIterators | ||||
| template <class CountingIterator> | ||||
| void category_test(CountingIterator start, CountingIterator finish, std::bidirectional_iterator_tag) | ||||
| { | ||||
|     if (finish != start | ||||
|         && finish != boost::next(start) | ||||
|         && finish != boost::next(boost::next(start))) | ||||
|     { | ||||
|         // Note that this test requires a that the first argument is | ||||
|         // dereferenceable /and/ a valid iterator prior to the first argument | ||||
|         boost::bidirectional_iterator_test(boost::next(start), boost::next(*start), boost::next(boost::next(*start))); | ||||
|     } | ||||
| } | ||||
|  | ||||
| template <class CountingIterator> | ||||
| void category_test(CountingIterator start, CountingIterator finish, std::forward_iterator_tag) | ||||
| { | ||||
|     if (finish != start && finish != boost::next(start)) | ||||
|         boost::forward_iterator_test(start, *start, boost::next(*start)); | ||||
| } | ||||
|  | ||||
| template <class CountingIterator> | ||||
| void test_aux(CountingIterator start, CountingIterator finish) | ||||
| { | ||||
|     typedef typename CountingIterator::iterator_category category; | ||||
|     typedef typename CountingIterator::value_type value_type; | ||||
|  | ||||
|     // If it's a RandomAccessIterator we can do a few delicate tests | ||||
|     category_test(start, finish, category()); | ||||
|      | ||||
|     // Okay, brute force... | ||||
|     for (CountingIterator p = start; p != finish && boost::next(p) != finish; ++p) | ||||
|     { | ||||
|         assert(boost::next(*p) == *boost::next(p)); | ||||
|     } | ||||
|  | ||||
|     // prove that a reference can be formed to these values | ||||
|     typedef typename CountingIterator::value_type value; | ||||
|     const value* q = &*start; | ||||
|     (void)q; // suppress unused variable warning | ||||
| } | ||||
|  | ||||
| template <class Incrementable> | ||||
| void test(Incrementable start, Incrementable finish) | ||||
| { | ||||
|     test_aux(boost::make_counting_iterator(start), boost::make_counting_iterator(finish)); | ||||
| } | ||||
|  | ||||
| template <class Integer> | ||||
| void test_integer(Integer* = 0) // default arg works around MSVC bug | ||||
| { | ||||
|     Integer start = 0; | ||||
|     Integer finish = 120; | ||||
|     test(start, finish); | ||||
| } | ||||
|  | ||||
| template <class Container> | ||||
| void test_container(Container* = 0)  // default arg works around MSVC bug | ||||
| { | ||||
|     Container c(1 + (unsigned)rand() % 1673); | ||||
|  | ||||
|     const typename Container::iterator start = c.begin(); | ||||
|      | ||||
|     // back off by 1 to leave room for dereferenceable value at the end | ||||
|     typename Container::iterator finish = start; | ||||
|     std::advance(finish, c.size() - 1); | ||||
|      | ||||
|     test(start, finish); | ||||
|  | ||||
|     typedef typename Container::const_iterator const_iterator; | ||||
|     test(const_iterator(start), const_iterator(finish)); | ||||
| } | ||||
|  | ||||
| class my_int1 { | ||||
| public: | ||||
|   my_int1() { } | ||||
|   my_int1(int x) : m_int(x) { } | ||||
|   my_int1& operator++() { ++m_int; return *this; } | ||||
|   bool operator==(const my_int1& x) const { return m_int == x.m_int; } | ||||
| private: | ||||
|   int m_int; | ||||
| }; | ||||
|  | ||||
| namespace boost { | ||||
|   template <> | ||||
|   struct counting_iterator_traits<my_int1> { | ||||
|     typedef std::ptrdiff_t difference_type; | ||||
|     typedef std::forward_iterator_tag iterator_category; | ||||
|   }; | ||||
| } | ||||
|  | ||||
| class my_int2 { | ||||
| public: | ||||
|   typedef void value_type; | ||||
|   typedef void pointer; | ||||
|   typedef void reference; | ||||
|   typedef std::ptrdiff_t difference_type; | ||||
|   typedef std::bidirectional_iterator_tag iterator_category; | ||||
|  | ||||
|   my_int2() { } | ||||
|   my_int2(int x) : m_int(x) { } | ||||
|   my_int2& operator++() { ++m_int; return *this; } | ||||
|   my_int2& operator--() { --m_int; return *this; } | ||||
|   bool operator==(const my_int2& x) const { return m_int == x.m_int; } | ||||
| private: | ||||
|   int m_int; | ||||
| }; | ||||
|  | ||||
| class my_int3 { | ||||
| public: | ||||
|   typedef void value_type; | ||||
|   typedef void pointer; | ||||
|   typedef void reference; | ||||
|   typedef std::ptrdiff_t difference_type; | ||||
|   typedef std::random_access_iterator_tag iterator_category; | ||||
|  | ||||
|   my_int3() { } | ||||
|   my_int3(int x) : m_int(x) { } | ||||
|   my_int3& operator++() { ++m_int; return *this; } | ||||
|   my_int3& operator+=(std::ptrdiff_t n) { m_int += n; return *this; } | ||||
|   std::ptrdiff_t operator-(const my_int3& x) const { return m_int - x.m_int; } | ||||
|   my_int3& operator--() { --m_int; return *this; } | ||||
|   bool operator==(const my_int3& x) const { return m_int == x.m_int; } | ||||
|   bool operator!=(const my_int3& x) const { return m_int != x.m_int; } | ||||
|   bool operator<(const my_int3& x) const { return m_int < x.m_int; } | ||||
| private: | ||||
|   int m_int; | ||||
| }; | ||||
|  | ||||
| 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 | ||||
|  | ||||
|    // wrapping an iterator or non-built-in integer type causes an INTERNAL | ||||
|    // COMPILER ERROR in MSVC without STLport. I'm clueless as to why. | ||||
| #if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT) | ||||
|     // Test user-defined type. | ||||
|     test_integer<my_int1>(); | ||||
|     test_integer<my_int2>(); | ||||
|     test_integer<my_int3>(); | ||||
|      | ||||
|    // 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]; | ||||
|     test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1)); | ||||
| #endif | ||||
|     std::cout << "test successful " << std::endl; | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										36
									
								
								current_function.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								current_function.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | ||||
| <html> | ||||
| 	<head> | ||||
| 		<title>Boost: current_function.hpp documentation</title> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||||
| 	</head> | ||||
| 	<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> | ||||
| 		<table border="0" width="100%"> | ||||
| 			<tr> | ||||
| 				<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> | ||||
| 				</td> | ||||
| 				<td align="center"> | ||||
| 					<h1>current_function.hpp</h1> | ||||
| 				</td> | ||||
| 			</tr> | ||||
| 			<tr> | ||||
| 				<td colspan="2" height="64"> </td> | ||||
| 			</tr> | ||||
| 		</table> | ||||
| 		<p> | ||||
| 			The header <STRONG><boost/current_function.hpp></STRONG> defines a single  | ||||
| 			macro, <STRONG>BOOST_CURRENT_FUNCTION</STRONG>,<STRONG> </STRONG>similar to the  | ||||
| 			C99 predefined identifier <STRONG>__func__</STRONG>. | ||||
| 		</p> | ||||
| 		<P><STRONG>BOOST_CURRENT_FUNCTION</STRONG> expands to a string literal containing  | ||||
| 			the (fully qualified, if possible) name of the enclosing function. If there is  | ||||
| 			no enclosing function, the behavior is undefined.</P> | ||||
| 		<p>Some compilers do not provide a way to obtain the name of the current enclosing  | ||||
| 			function. On such compilers, the string literal has an unspecified value.</p> | ||||
| 		<p> | ||||
| 			<br> | ||||
| 			<small>Copyright <20> 2002 by Peter Dimov. Distributed under the Boost Software License, Version  | ||||
| 				1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or  | ||||
| 				copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> | ||||
| 	</body> | ||||
| </html> | ||||
							
								
								
									
										40
									
								
								current_function_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								current_function_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  current_function_test.cpp - a test for boost/current_function.hpp | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/current_function.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <cstdio> | ||||
|  | ||||
| void message(char const * file, long line, char const * func, char const * msg) | ||||
| { | ||||
| #if !defined(BOOST_NO_STDC_NAMESPACE) | ||||
|     using std::printf; | ||||
| #endif | ||||
|  | ||||
|     printf("%s(%ld): %s in function '%s'\n", file, line, msg, func); | ||||
| } | ||||
|  | ||||
| #define MESSAGE(msg) message(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, msg) | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     MESSAGE("assertion failed"); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										389
									
								
								enable_if.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										389
									
								
								enable_if.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,389 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | ||||
|             "http://www.w3.org/TR/REC-html40/loose.dtd"> | ||||
| <HTML> | ||||
| <HEAD><TITLE>enable_if</TITLE> | ||||
|  | ||||
| <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||
| <META name="GENERATOR" content="Microsoft FrontPage 5.0"> | ||||
| </HEAD> | ||||
| <BODY > | ||||
| <!--HEVEA command line is: hevea -nosymb -noiso -pedantic -v enable_if_docs_for_boost.tex --> | ||||
| <!--HTMLHEAD--> | ||||
| <!--ENDHTML--> | ||||
| <!--PREFIX <ARG ></ARG>--> | ||||
| <!--CUT DEF section 1 --> | ||||
| <BR> | ||||
| <BR> | ||||
|  | ||||
|  | ||||
| <h1> | ||||
| <img border="0" src="../../boost.png" align="center" width="277" height="86">enable_if</h1> | ||||
| <BR> | ||||
| <BR> | ||||
| Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine.<BR> | ||||
| <BR> | ||||
| <!--TOC section Introduction--> | ||||
|  | ||||
| <H2><A NAME="htoc1">1</A>  Introduction</H2><!--SEC END --> | ||||
|  | ||||
| <A NAME="introduction"></A> | ||||
| The <TT>enable_if</TT> family of templates is a set of tools to allow a function template or a class template specialization  | ||||
| to include or exclude itself from a set of matching functions or specializations | ||||
| based on properties of its template arguments.  | ||||
| For example, one can define function templates that | ||||
| are only enabled for, and thus only match, an arbitrary set of types | ||||
| defined by a traits class. The <TT>enable_if</TT> templates can also be | ||||
| applied to enable class template specializations. Applications of | ||||
| <TT>enable_if</TT> are discussed in length | ||||
| in [<A HREF="#jarvi:03:cuj_arbitrary_overloading"><CITE>1</CITE></A>] and [<A HREF="#jarvi:03:c++typeclasses"><CITE>2</CITE></A>].<BR> | ||||
| <BR> | ||||
| <!--TOC subsection Synopsis--> | ||||
|  | ||||
| <H3><A NAME="htoc2">1.1</A>  Synopsis</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:synopsis"></A> | ||||
| <PRE>namespace boost { | ||||
|   template <class Cond, class T = void> struct enable_if; | ||||
|   template <class Cond, class T = void> struct disable_if; | ||||
|   template <class Cond, class T> struct lazy_enable_if; | ||||
|   template <class Cond, class T> struct lazy_disable_if; | ||||
|  | ||||
|   template <bool B, class T = void> struct enable_if_c; | ||||
|   template <bool B, class T = void> struct disable_if_c; | ||||
|   template <bool B, class T> struct lazy_enable_if_c; | ||||
|   template <bool B, class T> struct lazy_disable_if_c; | ||||
| } | ||||
| </PRE> | ||||
| <!--TOC subsection Background--> | ||||
|  | ||||
| <H3><A NAME="htoc3">1.2</A>  Background</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:background"></A> | ||||
| Sensible operation of template function overloading in C++ relies | ||||
| on the <EM>SFINAE</EM> (substitution-failure-is-not-an-error) | ||||
| principle [<A HREF="#vandevoorde2002:templates"><CITE>3</CITE></A>]: if an invalid argument | ||||
| or return type is formed during the instantiation of a function | ||||
| template, the instantiation is removed from the overload resolution | ||||
| set instead of causing a compilation error. The following example,  | ||||
| taken from [<A HREF="#jarvi:03:cuj_arbitrary_overloading"><CITE>1</CITE></A>], | ||||
| demonstrates why this is important: | ||||
| <PRE>int negate(int i) { return -i; } | ||||
|  | ||||
| template <class F> | ||||
| typename F::result_type negate(const F& f) { return -f(); } | ||||
|  | ||||
| </PRE> | ||||
| Suppose the compiler encounters the call <TT>negate(1)</TT>. The first | ||||
| definition is obviously a better match, but the compiler must | ||||
| nevertheless consider (and instantiate the prototypes) of both | ||||
| definitions to find this out. Instantiating the latter definition with | ||||
| <TT>F</TT> as <TT>int</TT> would result in: | ||||
| <PRE>int::result_type negate(const int&); | ||||
|  | ||||
| </PRE> | ||||
| where the return type is invalid. If this was an error, adding an unrelated function template  | ||||
| (that was never called) could break otherwise valid code. | ||||
| Due to the SFINAE principle the above example is not, however, erroneous.  | ||||
| The latter definition of <TT>negate</TT> is simply removed from the overload resolution set.<BR> | ||||
| <BR> | ||||
| The <TT>enable_if</TT> templates are tools for controlled creation of the SFINAE | ||||
| conditions.<BR> | ||||
| <BR> | ||||
| <!--TOC section The <TT>enable_if</TT> templates--> | ||||
|  | ||||
| <H2><A NAME="htoc4">2</A>  The <TT>enable_if</TT> templates</H2><!--SEC END --> | ||||
|  | ||||
| <A NAME="enable_if"></A> | ||||
| The names of the <TT>enable_if</TT> templates have three parts: an optional <TT>lazy_</TT> tag,  | ||||
| either <TT>enable_if</TT> or <TT>disable_if</TT>, and an optional <TT>_c</TT> tag. | ||||
| All eight combinations of these parts are supported. | ||||
| The meaning of the <TT>lazy_</TT> tag is described in Section <A HREF="#sec:enable_if_lazy">3.3</A>. | ||||
| The second part of the name indicates whether a true condition argument should  | ||||
| enable or disable the current overload. | ||||
| The third part of the name indicates whether the condition argument is a <TT>bool</TT> value  | ||||
| (<TT>_c</TT> suffix), or a type containing a static <TT>bool</TT> constant named <TT>value</TT> (no suffix). | ||||
| The latter version interoperates with Boost.MPL. <BR> | ||||
| <BR> | ||||
| The definitions of <TT>enable_if_c</TT> and <TT>enable_if</TT> are as follows (we use <TT>enable_if</TT> templates  | ||||
| unqualified but they are in the <TT>boost</TT> namespace). | ||||
| <PRE>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> {}; | ||||
|  | ||||
| </PRE> | ||||
| An instantiation of the <TT>enable_if_c</TT> template with the parameter | ||||
| <TT>B</TT> as <TT>true</TT> contains a member type <TT>type</TT>, defined | ||||
| to be <TT>T</TT>. If <TT>B</TT> is | ||||
| <TT>false</TT>, no such member is defined. Thus  | ||||
| <TT>enable_if_c<B, T>::type</TT> is either a valid or an invalid type | ||||
| expression, depending on the value of <TT>B</TT>. | ||||
| When valid, <TT>enable_if_c<B, T>::type</TT> equals <TT>T</TT>. | ||||
| The <TT>enable_if_c</TT> template can thus be used for controlling when functions are considered for | ||||
| overload resolution and when they are not.  | ||||
| For example, the following function is defined for all arithmetic types (according to the | ||||
| classification of the <A HREF="../type_traits/index.html">Boost type_traits library</A>): | ||||
| <PRE>template <class T> | ||||
| typename enable_if_c<boost::is_arithmetic<T>::value, T>::type  | ||||
| foo(T t) { return t; } | ||||
|  | ||||
| </PRE> | ||||
| The <TT>disable_if_c</TT> template is provided as well, and has the | ||||
| same functionality as <TT>enable_if_c</TT> except for the negated condition. The following | ||||
| function is enabled for all non-arithmetic types. | ||||
| <PRE>template <class T> | ||||
| typename disable_if_c<boost::is_arithmetic<T>::value, T>::type  | ||||
| bar(T t) { return t; } | ||||
|  | ||||
| </PRE> | ||||
| For easier syntax in some cases and interoperation with Boost.MPL we provide versions of | ||||
| the <TT>enable_if</TT> templates taking any type with a <TT>bool</TT> member constant named  | ||||
| <TT>value</TT> as the condition argument. | ||||
| The MPL <TT>bool_</TT>, <TT>and_</TT>, <TT>or_</TT>, and <TT>not_</TT> templates are likely to be  | ||||
| useful for creating such types. Also, the traits classes in the Boost.Type_traits library  | ||||
| follow this convention.  | ||||
| For example, the above example function <TT>foo</TT> can be alternatively written as: | ||||
| <PRE>template <class T> | ||||
| typename enable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t) { return t; } | ||||
|  | ||||
| </PRE> | ||||
| <!--TOC section Using <TT>enable_if</TT>--> | ||||
|  | ||||
| <H2><A NAME="htoc5">3</A>  Using <TT>enable_if</TT></H2><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:using_enable_if"></A> | ||||
| The <TT>enable_if</TT> templates are defined in | ||||
| <TT>boost/utility/enable_if.hpp</TT>, which is included by <TT>boost/utility.hpp</TT>.<BR> | ||||
| <BR> | ||||
| The <TT>enable_if</TT> template can be used either as the return type, or as an  | ||||
| extra argument. For example, the <TT>foo</TT> function in the previous section could also be written | ||||
| as: | ||||
| <PRE>template <class T> | ||||
| T foo(T t, typename enable_if<boost::is_arithmetic<T> >::type* dummy = 0);  | ||||
|  | ||||
| </PRE>Hence, an extra parameter of type <TT>void*</TT> is added, but it is given  | ||||
| a default value to keep the parameter hidden from client code. | ||||
| Note that the second template argument was not given to <TT>enable_if</TT>, as the default  | ||||
| <TT>void</TT> gives the desired behavior.<BR> | ||||
| <BR> | ||||
| Whether to write the enabler as an argument or within the return type is | ||||
| largely a matter of taste, but for certain functions, only one | ||||
| alternative is possible: | ||||
| <UL><LI> | ||||
| Operators have a fixed number of arguments, thus <TT>enable_if</TT> must be used in the return type. | ||||
| <LI>Constructors and destructors do not have a return type; an extra argument is the only option. | ||||
| <LI>There does not seem to be a way to specify an enabler for a conversion operator. Converting constructors, | ||||
| however, can have enablers as extra default arguments. | ||||
| </UL> | ||||
| <!--TOC subsection Enabling template class specializations--> | ||||
|  | ||||
| <H3><A NAME="htoc6">3.1</A>  Enabling template class specializations</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:enable_if_classes"></A> | ||||
| Class template specializations can be enabled or disabled with <TT>enable_if</TT>. | ||||
| One extra template parameter needs to be added for the enabler expressions. | ||||
| This parameter has the default value <TT>void</TT>. | ||||
| For example: | ||||
| <PRE>template <class T, class Enable = void>  | ||||
| class A { ... }; | ||||
|  | ||||
| template <class T> | ||||
| class A<T, typename enable_if<is_integral<T> >::type> { ... }; | ||||
|  | ||||
| template <class T> | ||||
| class A<T, typename enable_if<is_float<T> >::type> { ... }; | ||||
|  | ||||
| </PRE>Instantiating <TT>A</TT> with any integral type matches the first specialization, | ||||
| whereas any floating point type matches the second one. All other types | ||||
| match the primary template. | ||||
| The condition can be any compile-time boolean expression that depends on the  | ||||
| template arguments of the class. | ||||
| Note that again, the second argument to <TT>enable_if</TT> is not needed; the default (<TT>void</TT>)  | ||||
| is the correct value.<BR> | ||||
| <BR> | ||||
| <!--TOC subsection Overlapping enabler conditions--> | ||||
|  | ||||
| <H3><A NAME="htoc7">3.2</A>  Overlapping enabler conditions</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:overlapping_conditions"></A> | ||||
| Once the compiler has examined the enabling conditions and included the | ||||
| function into the overload resolution set, normal C++ overload resolution  | ||||
| rules are used to select the best matching function. | ||||
| In particular, there is no ordering between enabling conditions. | ||||
| Function templates with enabling conditions that are not mutually exclusive can  | ||||
| lead to ambiguities. For example: | ||||
| <PRE>template <class T> | ||||
| typename enable_if<boost::is_integral<T>, void>::type  | ||||
| foo(T t) {} | ||||
|  | ||||
| template <class T> | ||||
| typename enable_if<boost::is_arithmetic<T>, void>::type  | ||||
| foo(T t) {} | ||||
|  | ||||
| </PRE> | ||||
| All integral types are also arithmetic. Therefore, say, for the call <TT>foo(1)</TT>, | ||||
| both conditions are true and both functions are thus in the overload resolution set. | ||||
| They are both equally good matches and thus ambiguous. | ||||
| Of course, more than one enabling condition can be simultaneously true as long as  | ||||
| other arguments disambiguate the functions.<BR> | ||||
| <BR> | ||||
| The above discussion applies to using <TT>enable_if</TT> in class template | ||||
| partial specializations as well.<BR> | ||||
| <BR> | ||||
| <!--TOC subsection Lazy <TT>enable_if</TT>--> | ||||
|  | ||||
| <H3><A NAME="htoc8">3.3</A>  Lazy <TT>enable_if</TT></H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:enable_if_lazy"></A> | ||||
| In some cases it is necessary to avoid instantiating part of a | ||||
| function signature unless an enabling condition is true. For example: | ||||
| <PRE>template <class T, class U> class mult_traits; | ||||
|  | ||||
| template <class T, class U> | ||||
| typename enable_if<is_multipliable<T, U>, typename mult_traits<T, U>::type>::type | ||||
| operator*(const T& t, const U& u) { ... } | ||||
|  | ||||
| </PRE>Assume the class template <TT>mult_traits</TT> is a traits class defining  | ||||
| the resulting type of a multiplication operator. The <TT>is_multipliable</TT> traits | ||||
| class specifies for which types to enable the operator. Whenever | ||||
| <TT>is_multipliable<A, B>::value</TT> is <TT>true</TT> for some types <TT>A</TT> and <TT>B</TT>, | ||||
| then <TT>mult_traits<A, B>::type</TT> is defined.<BR> | ||||
| <BR> | ||||
| Now, trying to invoke (some other overload) of <TT>operator*</TT> with, say, operand types <TT>C</TT> and <TT>D</TT>  | ||||
| for which <TT>is_multipliable<C, D>::value</TT> is <TT>false</TT>  | ||||
| and <TT>mult_traits<C, D>::type</TT> is not defined is an error on some compilers.  | ||||
| The SFINAE principle is not applied because | ||||
| the invalid type occurs as an argument to another template. The <TT>lazy_enable_if</TT>  | ||||
| and <TT>lazy_disable_if</TT> templates (and their <TT>_c</TT> versions) can be used in such | ||||
| situations: | ||||
| <PRE>template<class T, class U> | ||||
| typename lazy_enable_if<is_multipliable<T, U>, mult_traits<T, U> >::type | ||||
| operator*(const T& t, const U& u) { ... } | ||||
|  | ||||
| </PRE>The second argument of <TT>lazy_enable_if</TT> must be a class type | ||||
| that defines a nested type named <TT>type</TT> whenever the first | ||||
| parameter (the condition) is true.<BR> | ||||
| <BR> | ||||
| <!--TOC paragraph Note--> | ||||
|  | ||||
| <H5>Note</H5><!--SEC END --> | ||||
|  | ||||
| Referring to one member type or static constant in a traits class | ||||
| causes all of the members (type and static constant) of that | ||||
| specialization to be instantiated. Therefore, if your traits classes | ||||
| can sometimes contain invalid types, you should use two distinct | ||||
| templates for describing the conditions and the type mappings. In the | ||||
| above example, <TT>is_multipliable<T, U>::value</TT> defines when | ||||
| <TT>mult_traits<T, U>::type</TT> is valid.<BR> | ||||
| <BR> | ||||
| <!--TOC subsection Compiler workarounds--> | ||||
|  | ||||
| <H3><A NAME="htoc9">3.4</A>  Compiler workarounds</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:workarounds"></A> | ||||
| Some compilers flag functions as ambiguous if the only distinguishing factor is a different  | ||||
| condition in an enabler (even though the functions could never be ambiguous). For example, | ||||
| some compilers (e.g. GCC 3.2) diagnose the following two functions as ambiguous: | ||||
| <PRE>template <class T> | ||||
| typename enable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t); | ||||
|  | ||||
| template <class T> | ||||
| typename disable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t); | ||||
|  | ||||
| </PRE>Two workarounds can be applied: | ||||
| <UL><LI> | ||||
| Use an extra dummy parameter which disambiguates the functions. Use a default value for | ||||
| it to hide the parameter from the caller. For example: | ||||
| <PRE>template <int> struct dummy { dummy(int) {} }; | ||||
|  | ||||
| template <class T> | ||||
| typename enable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t, dummy<0> = 0); | ||||
|  | ||||
| template <class T> | ||||
| typename disable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t, dummy<1> = 0); | ||||
| </PRE><BR> | ||||
| <BR> | ||||
| <LI>Define the functions in different namespaces and bring them into a common | ||||
| namespace with <TT>using</TT> declarations: | ||||
| <PRE>namespace A { | ||||
|   template <class T> | ||||
|   typename enable_if<boost::is_arithmetic<T>, T>::type  | ||||
|   foo(T t); | ||||
| } | ||||
|  | ||||
| namespace B { | ||||
|   template <class T> | ||||
|   typename disable_if<boost::is_arithmetic<T>, T>::type  | ||||
|   foo(T t); | ||||
| } | ||||
|  | ||||
| using A::foo; | ||||
| using B::foo; | ||||
|  | ||||
| </PRE> | ||||
| Note that the second workaround above cannot be used for member | ||||
| templates. On the other hand, operators do not accept extra arguments, | ||||
| which makes the first workaround unusable. As the net effect, | ||||
| neither of the workarounds are of assistance for templated operators that | ||||
| need to be defined as member functions (assignment and | ||||
| subscript operators). | ||||
| </UL> | ||||
| <!--TOC section Acknowledgements--> | ||||
|  | ||||
| <H2><A NAME="htoc10">4</A>  Acknowledgements</H2><!--SEC END --> | ||||
|  | ||||
| We are grateful to Howard Hinnant, Jason Shirk, Paul Mensonides, and Richard | ||||
| Smith whose findings have influenced the library.<BR> | ||||
| <BR> | ||||
| <!--TOC section References--> | ||||
|  | ||||
| <H2>References</H2><!--SEC END --> | ||||
| <DL COMPACT=compact><DT><A NAME="jarvi:03:cuj_arbitrary_overloading"><FONT COLOR=purple>[1]</FONT></A><DD> | ||||
| Jaakko Järvi, Jeremiah Willcock, Howard Hinnant, and Andrew Lumsdaine. | ||||
| Function overloading based on arbitrary properties of types. | ||||
| <EM>C/C++ Users Journal</EM>, 21(6):25--32, June 2003.<BR> | ||||
| <BR> | ||||
| <DT><A NAME="jarvi:03:c++typeclasses"><FONT COLOR=purple>[2]</FONT></A><DD> | ||||
| Jaakko Järvi, Jeremiah Willcock, and Andrew Lumsdaine. | ||||
| Concept-controlled polymorphism. | ||||
| In Frank Pfennig and Yannis Smaragdakis, editors, <EM>Generative | ||||
|  Programming and Component Engineering</EM>, volume 2830 of <EM>LNCS</EM>, pages | ||||
|  228--244. Springer Verlag, September 2003.<BR> | ||||
| <BR> | ||||
| <DT><A NAME="vandevoorde2002:templates"><FONT COLOR=purple>[3]</FONT></A><DD> | ||||
| David Vandevoorde and Nicolai M. Josuttis. | ||||
| <EM>C++ Templates: The Complete Guide</EM>. | ||||
| Addison-Wesley, 2002.</DL> | ||||
|  | ||||
| <hr/> | ||||
|    <p>Copyright Jaakko Järvi, Jeremiah Willcock and Andrew Lumsdaine<BR> | ||||
| <EM>{jajarvi|jewillco|lums}@osl.iu.edu</EM><BR> | ||||
| Indiana University<BR> | ||||
| Open Systems Lab<br/> | ||||
| Use, modification and distribution are subject to the | ||||
| Boost Software License, Version 1.0. | ||||
| (See accompanying file LICENSE_1_0.txt | ||||
| or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> | ||||
|    http://www.boost.org/LICENSE_1_0.txt | ||||
| </a>). | ||||
| </p> | ||||
| <!--HTMLFOOT--> | ||||
| <!--ENDHTML--> | ||||
| <!--FOOTER--> | ||||
| <HR SIZE=2> | ||||
| <BLOCKQUOTE><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by | ||||
| </EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>. | ||||
| </EM></BLOCKQUOTE> | ||||
| </BODY> | ||||
| </HTML> | ||||
							
								
								
									
										23
									
								
								enable_if/test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								enable_if/test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # Copyright David Abrahams 2003. | ||||
| # Distributed under the Boost Software License, Version 1.0.  | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at  | ||||
| # http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| # For more information, see http://www.boost.org/ | ||||
|  | ||||
| project | ||||
|     : requirements <library>/boost/test//boost_test_exec_monitor | ||||
|     ; | ||||
|  | ||||
| test-suite utility/enable_if | ||||
|         : | ||||
|         [ run constructors.cpp ] | ||||
|         [ run dummy_arg_disambiguation.cpp ] | ||||
|         [ run lazy.cpp ] | ||||
|         [ run lazy_test.cpp ] | ||||
|         [ run member_templates.cpp ] | ||||
|         [ run namespace_disambiguation.cpp ] | ||||
|         [ run no_disambiguation.cpp ] | ||||
|         [ run partial_specializations.cpp ] | ||||
|     ; | ||||
|  | ||||
							
								
								
									
										62
									
								
								enable_if/test/constructors.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								enable_if/test/constructors.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) 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 Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits.hpp> | ||||
|  | ||||
| using boost::enable_if; | ||||
| using boost::disable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| struct container { | ||||
|   bool my_value; | ||||
|  | ||||
|   template <class T> | ||||
|   container(const T&, const typename enable_if<is_arithmetic<T>, T>::type * = 0): | ||||
|   my_value(true) {} | ||||
|  | ||||
|   template <class T> | ||||
|   container(const T&, const typename disable_if<is_arithmetic<T>, T>::type * = 0): | ||||
|   my_value(false) {} | ||||
| }; | ||||
|  | ||||
| // example from Howard Hinnant (tests enable_if template members of a templated class) | ||||
| template <class charT> | ||||
| struct xstring | ||||
| { | ||||
|   template <class It> | ||||
|   xstring(It begin, It end, typename  | ||||
|           disable_if<is_arithmetic<It> >::type* = 0) | ||||
|     : data(end-begin) {} | ||||
|    | ||||
|   int data; | ||||
| }; | ||||
|  | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(container(1).my_value); | ||||
|   BOOST_CHECK(container(1.0).my_value); | ||||
|  | ||||
|   BOOST_CHECK(!container("1").my_value);   | ||||
|   BOOST_CHECK(!container(static_cast<void*>(0)).my_value);   | ||||
|  | ||||
|   char sa[] = "123456"; | ||||
|   BOOST_CHECK(xstring<char>(sa, sa+6).data == 6); | ||||
|  | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										46
									
								
								enable_if/test/dummy_arg_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								enable_if/test/dummy_arg_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) 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 Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::enable_if; | ||||
| using boost::disable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| template <int N> struct dummy { | ||||
|   dummy(int) {}; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| typename enable_if<is_arithmetic<T>, bool>::type | ||||
| arithmetic_object(T t, dummy<0> = 0) { return true; } | ||||
|  | ||||
| template<class T> | ||||
| typename disable_if<is_arithmetic<T>, bool>::type | ||||
| arithmetic_object(T t, dummy<1> = 0) { return false; } | ||||
|  | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(arithmetic_object(1)); | ||||
|   BOOST_CHECK(arithmetic_object(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!arithmetic_object("1"));   | ||||
|   BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										82
									
								
								enable_if/test/lazy.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								enable_if/test/lazy.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) 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 Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_same.hpp> | ||||
|  | ||||
| using boost::enable_if_c; | ||||
| using boost::lazy_enable_if_c; | ||||
|  | ||||
| // This class provides a reduced example of a traits class for | ||||
| // computing the result of multiplying two types.  The member typedef | ||||
| // 'type' in this traits class defines the return type of this | ||||
| // operator.  The return type member is invalid unless both arguments | ||||
| // for mult_traits are values that mult_traits expects (ints in this | ||||
| // case).  This kind of situation may arise if a traits class only | ||||
| // makes sense for some set of types, not all C++ types. | ||||
|  | ||||
| template <class T> struct is_int { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = (boost::is_same<T, int>::value)); | ||||
| }; | ||||
|  | ||||
| template <class T, class U> | ||||
| struct mult_traits { | ||||
|   typedef typename T::does_not_exist type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct mult_traits<int, int> { | ||||
|   typedef int type; | ||||
| }; | ||||
|  | ||||
|  | ||||
| // Next, a forwarding function mult() is defined.  It is enabled only | ||||
| // when both arguments are of type int.  The first version, using | ||||
| // non-lazy enable_if_c does not work. | ||||
|  | ||||
| #if 0 | ||||
| template <class T, class U> | ||||
| typename enable_if_c< | ||||
|   is_int<T>::value && is_int<U>::value, | ||||
|   typename mult_traits<T, U>::type | ||||
| >::type | ||||
| mult(const T& x, const U& y) {return x * y;} | ||||
| #endif | ||||
|  | ||||
| // A correct version uses lazy_enable_if_c. | ||||
| // This template removes compiler errors from invalid code used as an | ||||
| // argument to enable_if_c. | ||||
|  | ||||
| #if 1 | ||||
| template <class T, class U> | ||||
| typename lazy_enable_if_c< | ||||
|   is_int<T>::value & is_int<U>::value, | ||||
|   mult_traits<T, U>  | ||||
| >::type | ||||
| mult(const T& x, const U& y) {return x * y;} | ||||
| #endif | ||||
|  | ||||
| double mult(int i, double d) { return (double)i * d; } | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|  | ||||
|  | ||||
|   BOOST_CHECK(mult(1, 2) == 2); | ||||
|  | ||||
|   BOOST_CHECK(mult(1, 3.0) == 3.0); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										100
									
								
								enable_if/test/lazy_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								enable_if/test/lazy_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) 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 Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| // Testing all variations of lazy_enable_if. | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
| #include <boost/mpl/not.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_same.hpp> | ||||
|  | ||||
| using boost::lazy_enable_if; | ||||
| using boost::lazy_disable_if; | ||||
|  | ||||
| using boost::lazy_enable_if_c; | ||||
| using boost::lazy_disable_if_c; | ||||
|  | ||||
|  | ||||
| template <class T> | ||||
| struct is_int_or_double { | ||||
|   BOOST_STATIC_CONSTANT(bool,  | ||||
|     value = (boost::is_same<T, int>::value ||  | ||||
|              boost::is_same<T, double>::value)); | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct some_traits { | ||||
|   typedef typename T::does_not_exist type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct some_traits<int> { | ||||
|   typedef bool type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct some_traits<double> { | ||||
|   typedef bool type; | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct make_bool { | ||||
|   typedef bool type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct make_bool<int> {}; | ||||
|  | ||||
| template <> | ||||
| struct make_bool<double> {}; | ||||
|  | ||||
| namespace A { | ||||
|  | ||||
|   template<class T> | ||||
|   typename lazy_enable_if<is_int_or_double<T>, some_traits<T> >::type | ||||
|   foo(T t) { return true; } | ||||
|  | ||||
|   template<class T> | ||||
|   typename lazy_enable_if_c<is_int_or_double<T>::value, some_traits<T> >::type | ||||
|   foo2(T t) { return true; } | ||||
| } | ||||
|  | ||||
| namespace B { | ||||
|   template<class T> | ||||
|   typename lazy_disable_if<is_int_or_double<T>, make_bool<T> >::type | ||||
|   foo(T t) { return false; } | ||||
|  | ||||
|   template<class T> | ||||
|   typename lazy_disable_if_c<is_int_or_double<T>::value, make_bool<T> >::type | ||||
|   foo2(T t) { return false; } | ||||
| } | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   using namespace A; | ||||
|   using namespace B; | ||||
|   BOOST_CHECK(foo(1)); | ||||
|   BOOST_CHECK(foo(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!foo("1"));   | ||||
|   BOOST_CHECK(!foo(static_cast<void*>(0)));   | ||||
|  | ||||
|   BOOST_CHECK(foo2(1)); | ||||
|   BOOST_CHECK(foo2(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!foo2("1"));   | ||||
|   BOOST_CHECK(!foo2(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										43
									
								
								enable_if/test/member_templates.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								enable_if/test/member_templates.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) 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 Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::enable_if; | ||||
| using boost::disable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| struct container { | ||||
|   template <class T> | ||||
|   typename enable_if<is_arithmetic<T>, bool>::type | ||||
|   arithmetic_object(const T&, const int* /* disambiguate */ = 0) {return true;} | ||||
|  | ||||
|   template <class T> | ||||
|   typename disable_if<is_arithmetic<T>, bool>::type | ||||
|   arithmetic_object(const T&) {return false;} | ||||
| }; | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(container().arithmetic_object(1)); | ||||
|   BOOST_CHECK(container().arithmetic_object(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!container().arithmetic_object("1"));   | ||||
|   BOOST_CHECK(!container().arithmetic_object(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										47
									
								
								enable_if/test/namespace_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								enable_if/test/namespace_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) 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 Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
| #include <boost/mpl/not.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::enable_if; | ||||
| using boost::mpl::not_; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| namespace A { | ||||
|   template<class T> | ||||
|   typename enable_if<is_arithmetic<T>, bool>::type | ||||
|   arithmetic_object(T t) { return true; } | ||||
| } | ||||
|  | ||||
| namespace B { | ||||
|   template<class T> | ||||
|   typename enable_if<not_<is_arithmetic<T> >, bool>::type | ||||
|   arithmetic_object(T t) { return false; } | ||||
| } | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   using namespace A; | ||||
|   using namespace B; | ||||
|   BOOST_CHECK(arithmetic_object(1)); | ||||
|   BOOST_CHECK(arithmetic_object(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!arithmetic_object("1"));   | ||||
|   BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										43
									
								
								enable_if/test/no_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								enable_if/test/no_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) 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 Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
| #include <boost/mpl/not.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::mpl::not_; | ||||
| using boost::enable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| template<class T> | ||||
| typename enable_if<is_arithmetic<T>, bool>::type | ||||
| arithmetic_object(T t) { return true; } | ||||
|  | ||||
| template<class T> | ||||
| typename enable_if<not_<is_arithmetic<T> >, bool>::type | ||||
| arithmetic_object(T t) { return false; } | ||||
|  | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(arithmetic_object(1)); | ||||
|   BOOST_CHECK(arithmetic_object(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!arithmetic_object("1"));   | ||||
|   BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										67
									
								
								enable_if/test/partial_specializations.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								enable_if/test/partial_specializations.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) 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 Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::enable_if_c; | ||||
| using boost::disable_if_c; | ||||
| using boost::enable_if; | ||||
| using boost::disable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| template <class T, class Enable = void> | ||||
| struct tester; | ||||
|  | ||||
| template <class T> | ||||
| struct tester<T, typename enable_if_c<is_arithmetic<T>::value>::type> { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = true); | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct tester<T, typename disable_if_c<is_arithmetic<T>::value>::type> { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = false); | ||||
| }; | ||||
|  | ||||
| template <class T, class Enable = void> | ||||
| struct tester2; | ||||
|  | ||||
| template <class T> | ||||
| struct tester2<T, typename enable_if<is_arithmetic<T> >::type> { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = true); | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct tester2<T, typename disable_if<is_arithmetic<T> >::type> { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = false); | ||||
| }; | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(tester<int>::value); | ||||
|   BOOST_CHECK(tester<double>::value); | ||||
|  | ||||
|   BOOST_CHECK(!tester<char*>::value); | ||||
|   BOOST_CHECK(!tester<void*>::value); | ||||
|  | ||||
|   BOOST_CHECK(tester2<int>::value); | ||||
|   BOOST_CHECK(tester2<double>::value); | ||||
|  | ||||
|   BOOST_CHECK(!tester2<char*>::value); | ||||
|   BOOST_CHECK(!tester2<void*>::value); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -1,273 +0,0 @@ | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
| <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> | ||||
| <meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
| <title>Filter Iterator Adaptor Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|  | ||||
| <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" | ||||
| align="center" width="277" height="86"> | ||||
|  | ||||
| <h1>Filter Iterator Adaptor</h1> | ||||
|  | ||||
| Defined in header | ||||
| <a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a> | ||||
|  | ||||
|  | ||||
| <p> | ||||
| The filter iterator adaptor creates a view of an iterator range in | ||||
| which some elements of the range are skipped over. A <a | ||||
| href="http://www.sgi.com/tech/stl/Predicate.html">Predicate</a> | ||||
| function object controls which elements are skipped. When the | ||||
| predicate is applied to an element, if it returns <tt>true</tt> then | ||||
| the element is retained and if it returns <tt>false</tt> then the | ||||
| element is skipped over. | ||||
|  | ||||
|  | ||||
| <h2>Synopsis</h2> | ||||
|  | ||||
| <pre> | ||||
| namespace boost { | ||||
|   template <class Predicate, class BaseIterator, ...> | ||||
|   class filter_iterator_generator; | ||||
|  | ||||
|   template <class Predicate, class BaseIterator> | ||||
|   typename filter_iterator_generator<Predicate, BaseIterator>::type | ||||
|   make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate()); | ||||
| } | ||||
| </pre> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <h2><a name="filter_iterator_generator">The Filter Iterator Type | ||||
| Generator</a></h2> | ||||
|  | ||||
| The class <tt>filter_iterator_generator</tt> is a helper class whose | ||||
| purpose is to construct a filter iterator type.  The template | ||||
| parameters for this class are the <tt>Predicate</tt> function object | ||||
| type and the <tt>BaseIterator</tt> type that is being wrapped.  In | ||||
| most cases the associated types for the wrapped iterator can be | ||||
| deduced from <tt>std::iterator_traits</tt>, but in some situations the | ||||
| user may want to override these types, so there are also template | ||||
| parameters for each of the iterator's associated types. | ||||
|  | ||||
| <pre> | ||||
| template <class Predicate, class BaseIterator, | ||||
|           class Value, class Reference, class Pointer, class Category, class Distance> | ||||
| class filter_iterator_generator | ||||
| { | ||||
| public: | ||||
|   typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting filter iterator type  | ||||
| } | ||||
| </pre> | ||||
|  | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| The following example uses filter iterator to print out all the | ||||
| positive integers in an array.  | ||||
|  | ||||
| <pre> | ||||
| struct is_positive_number { | ||||
|   bool operator()(int x) { return 0 < x; } | ||||
| }; | ||||
| int main() { | ||||
|   int numbers[] = { 0, -1, 4, -3, 5, 8, -2 }; | ||||
|   const int N = sizeof(numbers)/sizeof(int); | ||||
|  | ||||
|   typedef boost::filter_iterator_generator<is_positive_number, int*, int>::type FilterIter; | ||||
|   is_positive_number predicate; | ||||
|   FilterIter::policies_type policies(predicate, numbers + N); | ||||
|   FilterIter filter_iter_first(numbers, policies); | ||||
|   FilterIter filter_iter_last(numbers + N, policies); | ||||
|  | ||||
|   std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|   return 0; | ||||
| } | ||||
| </pre> | ||||
| The output is: | ||||
| <pre> | ||||
| 4 5 8 | ||||
| </pre> | ||||
|  | ||||
|  | ||||
| <h3>Template Parameters</h3> | ||||
|  | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH>Parameter</TH><TH>Description</TH> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><a href="http://www.sgi.com/tech/stl/Predicate.html"><tt>Predicate</tt></a></TD> | ||||
| <TD>The function object that determines which elements are retained and which elements are skipped. | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>BaseIterator</tt></TD> | ||||
| <TD>The iterator type being wrapped. This type must at least be a model | ||||
|  of the <a href="http://www.sgi.com/tech/stl/InputIterator">InputIterator</a> concept.</TD> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>Value</tt></TD> | ||||
| <TD>The <tt>value_type</tt> of the resulting iterator, | ||||
| unless const. If const, a conforming compiler strips constness for the | ||||
| <tt>value_type</tt>. Typically the default for this parameter is the | ||||
| appropriate type<a href="#1">[1]</a>.<br> <b>Default:</b> | ||||
| <tt>std::iterator_traits<BaseIterator>::value_type</TD> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>Reference</tt></TD> | ||||
| <TD>The <tt>reference</tt> type of the resulting iterator, and in | ||||
| particular, the result type of <tt>operator*()</tt>. Typically the default for | ||||
| this parameter is the appropriate type.<br> <b>Default:</b> If | ||||
| <tt>Value</tt> is supplied, <tt>Value&</tt> is used. Otherwise | ||||
| <tt>std::iterator_traits<BaseIterator>::reference</tt> is | ||||
| used.</TD> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>Pointer</tt></TD> | ||||
| <TD>The <tt>pointer</tt> type of the resulting iterator, and in | ||||
|  particular, the result type of <tt>operator->()</tt>.  | ||||
|  Typically the default for | ||||
| this parameter is the appropriate type.<br> | ||||
| <b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>, | ||||
| otherwise <tt>std::iterator_traits<BaseIterator>::pointer</tt>.</TD> | ||||
| </TR> | ||||
|  | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>Category</tt></TD> | ||||
| <TD>The <tt>iterator_category</tt> type for the resulting iterator. | ||||
| Typically the | ||||
| default for this parameter is the appropriate type. If you override | ||||
| this parameter, do not use <tt>bidirectional_iterator_tag</tt> | ||||
| because filter iterators can not go in reverse.<br> | ||||
| <b>Default:</b> <tt>std::iterator_traits<BaseIterator>::iterator_category</tt></TD> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>Distance</tt></TD> | ||||
| <TD>The <tt>difference_type</tt> for the resulting iterator. Typically the default for | ||||
| this parameter is the appropriate type.<br> | ||||
| <b>Default:</b> <tt>std::iterator_traits<BaseIterator>::difference_type</TD> | ||||
| </TR> | ||||
|  | ||||
| </table> | ||||
|  | ||||
|  | ||||
| <h3>Model of</h3> | ||||
|  | ||||
| The filter iterator adaptor (the type | ||||
| <tt>filter_iterator_generator<...>::type</tt>) may be a model of <a | ||||
| href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> or <a | ||||
| href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a> | ||||
| depending on the adapted iterator type. | ||||
|  | ||||
|  | ||||
| <h3>Members</h3> | ||||
|  | ||||
| The filter iterator type implements all of the member functions and | ||||
| operators required of the <a | ||||
| href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a> | ||||
| concept.  In addition it has the following constructor: | ||||
|  | ||||
| <pre>filter_iterator_generator::type(const BaseIterator& it, const Policies& p = Policies())</pre> | ||||
|  | ||||
| <p> | ||||
| The policies type has only one public function, which is its constructor: | ||||
|  | ||||
| <pre>filter_iterator_generator::policies_type(const Predicate& p, const BaseIterator& end)</pre> | ||||
|  | ||||
| <p> | ||||
| <hr> | ||||
| <p> | ||||
|  | ||||
| <h2><a name="make_filter_iterator">The Make Filter Iterator Function</a></h2> | ||||
|  | ||||
| <pre> | ||||
| template <class Predicate, class BaseIterator> | ||||
| typename detail::filter_generator<Predicate, BaseIterator>::type | ||||
| make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate()) | ||||
| </pre> | ||||
|  | ||||
| This function provides a convenient way to create filter iterators. | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| In this example we print out all numbers in the array that are | ||||
| greater than negative two. | ||||
|  | ||||
| <pre> | ||||
| int main() | ||||
| { | ||||
|   int numbers[] = { 0, -1, 4, -3, 5, 8, -2 }; | ||||
|   const int N = sizeof(numbers)/sizeof(int); | ||||
|  | ||||
|   std::copy(boost::make_filter_iterator(numbers, numbers + N,  | ||||
| 					std::bind2nd(std::greater<int>(), -2)), | ||||
| 	    boost::make_filter_iterator(numbers + N, numbers + N,  | ||||
| 					std::bind2nd(std::greater<int>(), -2)), | ||||
| 	    std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
| } | ||||
| </pre> | ||||
| The output is: | ||||
| <pre> | ||||
| 0 -1 4 5 8  | ||||
| </pre> | ||||
|  | ||||
| <p> | ||||
| In the next example we print the positive numbers using the | ||||
| <tt>make_filter_iterator()</tt> function. | ||||
|  | ||||
| <pre> | ||||
| struct is_positive_number { | ||||
|   bool operator()(int x) { return 0 < x; } | ||||
| }; | ||||
| int main() | ||||
| { | ||||
|   int numbers[] = { 0, -1, 4, -3, 5, 8, -2 }; | ||||
|   const int N = sizeof(numbers)/sizeof(int); | ||||
|  | ||||
|   std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N), | ||||
| 	    boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N), | ||||
| 	    std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|   return 0; | ||||
| } | ||||
| </pre> | ||||
| The output is: | ||||
| <pre> | ||||
| 4 5 8 | ||||
| </pre> | ||||
|  | ||||
|  | ||||
| <h3>Notes</h3> | ||||
|  | ||||
| <a name="1">[1]</a> If the compiler does not support partial | ||||
| specialization and the wrapped iterator type is a builtin pointer then | ||||
| the <tt>Value</tt> type must be explicitly specified (don't use the | ||||
| default). | ||||
|  | ||||
|  | ||||
| <hr> | ||||
| <p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->09 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14894" --></p> | ||||
| <p><EFBFBD> Copyright Jeremy Siek 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> | ||||
|  | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
| @@ -1,53 +0,0 @@ | ||||
| // Example of using the filter iterator adaptor from | ||||
| // boost/iterator_adaptors.hpp. | ||||
|  | ||||
| //  (C) Copyright Jeremy Siek 1999. 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 <algorithm> | ||||
| #include <functional> | ||||
| #include <iostream> | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
|  | ||||
| struct is_positive_number { | ||||
|   bool operator()(int x) { return 0 < x; } | ||||
| }; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   int numbers[] = { 0, -1, 4, -3, 5, 8, -2 }; | ||||
|   const int N = sizeof(numbers)/sizeof(int); | ||||
|  | ||||
|   // Example using make_filter_iterator() | ||||
|   std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N), | ||||
| 	    boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N), | ||||
| 	    std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // Example using filter_iterator_generator | ||||
|   typedef boost::filter_iterator_generator<is_positive_number, int*, int>::type | ||||
|     FilterIter; | ||||
|   is_positive_number predicate; | ||||
|   FilterIter::policies_type policies(predicate, numbers + N); | ||||
|   FilterIter filter_iter_first(numbers, policies); | ||||
|   FilterIter filter_iter_last(numbers + N, policies); | ||||
|  | ||||
|   std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // Another example using make_filter_iterator() | ||||
|   std::copy(boost::make_filter_iterator(numbers, numbers + N,  | ||||
| 					std::bind2nd(std::greater<int>(), -2)), | ||||
| 	    boost::make_filter_iterator(numbers + N, numbers + N,  | ||||
| 					std::bind2nd(std::greater<int>(), -2)), | ||||
| 	    std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|    | ||||
|    | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,41 +0,0 @@ | ||||
| // (C) Copyright Jeremy Siek 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: | ||||
|  | ||||
| // 27 Feb 2001   Jeremy Siek | ||||
| //      Initial checkin. | ||||
|  | ||||
| #include <iostream> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| #include <boost/function_output_iterator.hpp> | ||||
|  | ||||
| struct string_appender { | ||||
|   string_appender(std::string& s) : m_str(s) { } | ||||
|   void operator()(const std::string& x) const { | ||||
|     m_str += x; | ||||
|   } | ||||
|   std::string& m_str; | ||||
| }; | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   std::vector<std::string> x; | ||||
|   x.push_back("hello"); | ||||
|   x.push_back(" "); | ||||
|   x.push_back("world"); | ||||
|   x.push_back("!"); | ||||
|  | ||||
|   std::string s = ""; | ||||
|   std::copy(x.begin(), x.end(),  | ||||
| 	    boost::make_function_output_iterator(string_appender(s))); | ||||
|    | ||||
|   std::cout << s << std::endl; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,169 +0,0 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN"> | ||||
|  | ||||
| <html> | ||||
| <head> | ||||
|     <meta name="generator" content="HTML Tidy, see www.w3.org"> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
|     <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> | ||||
|     <meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
|  | ||||
|     <title>Function Output Iterator Adaptor Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|          | ||||
|     <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align= | ||||
|     "center" width="277" height="86">  | ||||
|  | ||||
|     <h1>Function Output Iterator Adaptor</h1> | ||||
|     Defined in header <a href= | ||||
|     "../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a>  | ||||
|  | ||||
|     <p>The function output iterator adaptor makes it easier to create | ||||
|     custom output iterators. The adaptor takes a <a | ||||
|     href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary | ||||
|     Function</a> and creates a model of <a | ||||
|     href="http://www.sgi.com/tech/stl/OutputIterator.html">Output | ||||
|     Iterator</a>. Each item assigned to the output iterator is passed | ||||
|     as an argument to the unary function.  The motivation for this | ||||
|     iterator is that creating a C++ Standard conforming output | ||||
|     iterator is non-trivial, particularly because the proper | ||||
|     implementation usually requires a proxy object. On the other hand, | ||||
|     creating a function (or function object) is much simpler. | ||||
|  | ||||
|     <h2>Synopsis</h2> | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| namespace boost { | ||||
|   template <class UnaryFunction> | ||||
|   class function_output_iterator; | ||||
|  | ||||
|   template <class UnaryFunction> | ||||
|   function_output_iterator<UnaryFunction> | ||||
|   make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) | ||||
| } | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Example</h3> | ||||
|      | ||||
|     In this example we create an output iterator that appends | ||||
|     each item onto the end of a string, using the <tt>string_appender</tt> | ||||
|     function.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| #include <iostream> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| #include <boost/function_output_iterator.hpp> | ||||
|  | ||||
| struct string_appender { | ||||
|   string_appender(std::string& s) : m_str(s) { } | ||||
|   void operator()(const std::string& x) const { | ||||
|     m_str += x; | ||||
|   } | ||||
|   std::string& m_str; | ||||
| }; | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   std::vector<std::string> x; | ||||
|   x.push_back("hello"); | ||||
|   x.push_back(" "); | ||||
|   x.push_back("world"); | ||||
|   x.push_back("!"); | ||||
|  | ||||
|   std::string s = ""; | ||||
|   std::copy(x.begin(), x.end(),  | ||||
|             boost::make_function_output_iterator(string_appender(s))); | ||||
|    | ||||
|   std::cout << s << std::endl; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <hr> | ||||
|  | ||||
|     <h2><a name="function_output_iterator">The Function Output Iterator Class</a></h2> | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class UnaryFunction> | ||||
| class function_output_iterator; | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     The <tt>function_output_iterator</tt> class creates an <a | ||||
|     href="http://www.sgi.com/tech/stl/OutputIterator.html">Output | ||||
|     Iterator</a> out of a | ||||
|     <a href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary | ||||
|     Function</a>. Each item assigned to the output iterator is passed | ||||
|     as an argument to the unary function. | ||||
|  | ||||
|     <h3>Template Parameters</h3> | ||||
|  | ||||
|     <table border> | ||||
|       <tr> | ||||
|         <th>Parameter | ||||
|  | ||||
|         <th>Description | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>UnaryFunction</tt>  | ||||
|  | ||||
|         <td>The function type being wrapped. The return type of the | ||||
|         function is not used, so it can be <tt>void</tt>.  The | ||||
|         function must be a model of <a | ||||
|         href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary | ||||
|         Function</a>.</td> | ||||
|     </table> | ||||
|  | ||||
|     <h3>Concept Model</h3> | ||||
|     The function output iterator class is a model of <a | ||||
|     href="http://www.sgi.com/tech/stl/OutputIterator.html">Output | ||||
|     Iterator</a>. | ||||
|  | ||||
|     <h2>Members</h3> | ||||
|     The function output iterator implements the member functions | ||||
|     and operators required of the <a | ||||
|     href="http://www.sgi.com/tech/stl/OutputIterator.html">Output | ||||
|     Iterator</a> concept. In addition it has the following constructor: | ||||
| <pre> | ||||
| explicit function_output_iterator(const UnaryFunction& f = UnaryFunction()) | ||||
| </pre> | ||||
|    <br>     | ||||
|     <br> | ||||
|  | ||||
|     <hr> | ||||
|     <h2><a name="make_function_output_iterator">The Function Output Iterator Object | ||||
|     Generator</a></h2> | ||||
|  | ||||
|     The <tt>make_function_output_iterator()</tt> function provides a | ||||
|     more convenient way to create function output iterator objects. The | ||||
|     function saves the user the trouble of explicitly writing out the | ||||
|     iterator types. If the default argument is used, the function | ||||
|     type must be provided as an explicit template argument. | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class UnaryFunction> | ||||
| function_output_iterator<UnaryFunction> | ||||
| make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <hr> | ||||
|  | ||||
|     <p>© Copyright Jeremy Siek 2001. 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. | ||||
|  | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										163
									
								
								generator_iterator.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								generator_iterator.htm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <html> | ||||
| <head> | ||||
|   <meta http-equiv="Content-Language" content="en-us"> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> | ||||
|  | ||||
|   <title>Generator Iterator Adaptor Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|   <img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" | ||||
|   width="277" height="86"> | ||||
|  | ||||
|   <h1>Generator Iterator Adaptor</h1> | ||||
|  | ||||
|   <p>Defined in header <a href= | ||||
|   "../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a></p> | ||||
|  | ||||
|   <p>The generator iterator adaptor makes it easier to create custom input | ||||
|   iterators from 0-ary functions and function objects. The adaptor takes a | ||||
|   <a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a> and | ||||
|   creates a model of <a href= | ||||
|   "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>. Each | ||||
|   increment retrieves an item from the generator and makes it available to be | ||||
|   retrieved by dereferencing. The motivation for this iterator is that some | ||||
|   concepts can be more naturally expressed as a generator, while most STL | ||||
|   algorithms expect an iterator. An example is the <a href= | ||||
|   "../random/index.html">Random Number</a> library.</p> | ||||
|  | ||||
|   <h2>Synopsis</h2> | ||||
|  | ||||
|   <blockquote> | ||||
|     <pre> | ||||
| namespace boost { | ||||
|   template <class Generator> | ||||
|   class generator_iterator_policies; | ||||
|  | ||||
|   template <class Generator> | ||||
|   class generator_iterator_generator; | ||||
|  | ||||
|   template <class Generator> | ||||
|   typename generator_iterator_generator<Generator>::type | ||||
|   make_generator_iterator(Generator & gen); | ||||
| } | ||||
| </pre> | ||||
|   </blockquote> | ||||
|   <hr> | ||||
|  | ||||
|   <h2>The Generator Iterator Generator Class</h2> | ||||
|  | ||||
|   <p>The class generator_iterator_generator is a helper class whose purpose | ||||
|   is to construct a generator iterator type. The template parameter for this | ||||
|   class is the Generator function object type that is being wrapped. The | ||||
|   generator iterator adaptor only holds a reference (or pointer) to the | ||||
|   function object, therefore the function object must outlive the generator | ||||
|   iterator adaptor constructed from it.</p> | ||||
|   <pre> | ||||
| template <class Generator> | ||||
| class generator_iterator_generator | ||||
| { | ||||
| public: | ||||
|   typedef <i>unspecified</i> type; // the resulting generator iterator type  | ||||
| } | ||||
| </pre> | ||||
|  | ||||
|   <h3>Template Parameters</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Parameter</th> | ||||
|  | ||||
|       <th>Description</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td><tt><a href= | ||||
|       "http://www.sgi.com/tech/stl/Generator.html">Generator</a></tt></td> | ||||
|  | ||||
|       <td>The generator (0-ary function object) type being wrapped. The | ||||
|       return type of the function must be defined as | ||||
|       <tt>Generator::result_type</tt>. The function object must be a model of | ||||
|       <a href= | ||||
|       "http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Concept Model</h3> | ||||
|  | ||||
|   <p>The generator iterator class is a model of <a href= | ||||
|   "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.</p> | ||||
|  | ||||
|   <h3>Members</h3> | ||||
|  | ||||
|   <p>The generator iterator implements the member functions and operators | ||||
|   required of the <a href= | ||||
|   "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a> | ||||
|   concept.<br></p> | ||||
|   <hr> | ||||
|  | ||||
|   <h2><a name="make_generator_iterator" id="make_generator_iterator">The | ||||
|   Generator Iterator Object Generator</a></h2> | ||||
|  | ||||
|   <p>The <tt>make_generator_iterator()</tt> function provides a convenient | ||||
|   way to create generator iterator objects. The function saves the user the | ||||
|   trouble of explicitly writing out the iterator types.</p> | ||||
|  | ||||
|   <blockquote> | ||||
|     <pre> | ||||
| template <class Generator> | ||||
| typename generator_iterator_generator<Generator>::type | ||||
| make_generator_iterator(Generator & gen); | ||||
| </pre> | ||||
|   </blockquote> | ||||
|   <hr> | ||||
|  | ||||
|   <h3>Example</h3> | ||||
|  | ||||
|   <p>The following program shows how <code>generator_iterator</code> | ||||
|   transforms a generator into an input iterator.</p> | ||||
|  | ||||
|   <blockquote> | ||||
|     <pre> | ||||
| #include <iostream> | ||||
| #include <boost/generator_iterator.hpp> | ||||
|  | ||||
| class my_generator | ||||
| { | ||||
| public: | ||||
|   typedef int result_type; | ||||
|   my_generator() : state(0) { } | ||||
|   int operator()() { return ++state; } | ||||
| private: | ||||
|   int state; | ||||
| }; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   my_generator gen; | ||||
|   boost::generator_iterator_generator<my_generator>::type it = boost::make_generator_iterator(gen); | ||||
|   for(int i = 0; i < 10; ++i, ++it) | ||||
|     std::cout << *it << std::endl; | ||||
| } | ||||
| </pre> | ||||
|   </blockquote> | ||||
|   <hr> | ||||
|  | ||||
|   <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= | ||||
|   "http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" | ||||
|   height="31" width="88"></a></p> | ||||
|  | ||||
|   <p>Revised  | ||||
|   <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p> | ||||
|  | ||||
|   <p><i>Copyright © 2001 <a href= | ||||
|   "http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a></i></p> | ||||
|  | ||||
|   <p><i>Distributed under the Boost Software License, Version 1.0. (See | ||||
|   accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or | ||||
|   copy at <a href= | ||||
|   "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></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; | ||||
| } | ||||
							
								
								
									
										296
									
								
								in_place_factories.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								in_place_factories.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,296 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//SoftQuad Software//DTD HoTMetaL PRO 5.0::19981217::extensions to HTML 4.0//EN" "hmpro5.dtd"> | ||||
|  | ||||
| <HTML> | ||||
|  | ||||
| <HEAD> | ||||
| <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"> | ||||
| <TITLE>In_place_factory Documentation</TITLE> | ||||
| </HEAD> | ||||
|  | ||||
| <BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080"> | ||||
| <H2 align="left"><IMG SRC="../../boost.png" WIDTH="276" HEIGHT="86"></H2> | ||||
|  | ||||
| <blockquote> | ||||
|   <blockquote> | ||||
|     <blockquote> | ||||
|       <blockquote> | ||||
|         <blockquote> | ||||
|           <blockquote> | ||||
| <H2 align="left">Header <<A | ||||
| HREF="../../boost/utility/in_place_factory.hpp">boost/utility/in_place_factory.hpp</A>> </H2> | ||||
|  | ||||
| <H2 align="left">Header <<A | ||||
| HREF="../../boost/utility/typed_in_place_factory.hpp">boost/utility/typed_in_place_factory.hpp</A>> </H2> | ||||
|  | ||||
|           </blockquote> | ||||
|         </blockquote> | ||||
|       </blockquote> | ||||
|     </blockquote> | ||||
|   </blockquote> | ||||
| </blockquote> | ||||
| <p> </p> | ||||
|  | ||||
| <H2>Contents</H2> | ||||
| <DL CLASS="page-index"> | ||||
|   <DT><A HREF="#mot">Motivation</A></DT> | ||||
|   <DT><A HREF="#framework">Framework</A></DT> | ||||
|   <DT><A HREF="#specification">Specification</A></DT> | ||||
|   <DT><A HREF="#container-usage">Container-side Usage</A></DT> | ||||
|   <DT><A HREF="#user-usage">User-side Usage</A></DT> | ||||
| </DL> | ||||
|  | ||||
| <HR> | ||||
|  | ||||
| <H2><A NAME="mot"></A>Motivation</H2> | ||||
|  | ||||
| <p>Suppose we have a class</p> | ||||
| <pre>struct X | ||||
| { | ||||
|   X ( int, std:::string ) ; | ||||
| } ;</pre> | ||||
| <p>And a container for it which supports an empty state (that is, which can contain zero objects):</p> | ||||
| <pre>struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| } ;</pre> | ||||
| <p>A container designed to support an empty state typically doesn't require the contained type to be DefaultConstructible, | ||||
| but it typically requires it to be CopyConstructible as a mechanism to | ||||
| initialize the object to store:</p> | ||||
| <pre>struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| } ;</pre> | ||||
| <p>There is a subtle problem with this: since the mechanism used to initialize the stored object is copy construction, | ||||
| there must exist a previously constructed source object to copy from. This | ||||
| object is likely to be temporary and serve no purpose besides being the source</p> | ||||
| <pre>void foo() | ||||
| { | ||||
|   // Temporary object created. | ||||
|   C c( X(123,"hello") ) ; | ||||
| } | ||||
| </pre> | ||||
| <p>A solution to this problem is to support direct construction of the contained | ||||
| object right in the container's storage.<br> | ||||
| In this scheme, the user supplies the arguments for the X constructor | ||||
| directly to the container:</p> | ||||
| <pre>struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|    C ( int a0, std::string a1 ) : contained_ ( new X(a0,a1) ) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| } ;</pre> | ||||
| <pre>void foo() | ||||
| { | ||||
|   // Wrapped object constructed in-place | ||||
|   // No temporary created. | ||||
|   C c(123,"hello") ; | ||||
| } | ||||
| </pre> | ||||
| <p>Clearly, this solution doesn't scale well since the container must duplicate all the constructor overloads from the contained type | ||||
| (at least all those which are to be supported directly in the container).</p> | ||||
|  | ||||
| <H2><A NAME="framework"></A>Framework</H2> | ||||
| <p> | ||||
| This library proposes a framework to allow some containers to directly contruct contained objects in-place without requiring | ||||
| the entire set of constructor overloads ftom the contained type. It also allows the container to remove the CopyConstuctible | ||||
| requirement from the contained type since objects can be directly constructed in-place without need of a copy.<br> | ||||
| The only requirement on the container is that it must provide proper storage (that is, correctly aligned and sized). | ||||
| Naturally, the container will typically support uninitialized storage to avoid the in-place construction to override | ||||
| a fully-constructed object (as this would defeat the purpose of in-place construction) | ||||
| </p> | ||||
| <p>For this purpose, the framework provides two families of classes collectively called: InPlaceFactories and TypedInPlaceFactories.<br> | ||||
| Essentially, these classes hold a sequence of actual parameters and a method to contruct an object in place using these parameters. | ||||
| Each member of the family differs only in the number (and type) of the parameter list. The first family | ||||
| takes the type of the object to construct directly in method provided for that | ||||
| purpose, whereas the second family incorporates that type in the factory class | ||||
| itself..</p> | ||||
| <p>From the container POV, using the framework amounts to calling the factory's method to contruct the object in place. | ||||
| From the user POV, it amounts to creating the right factory object to hold the parameters and pass it to the container.<br> | ||||
| The following simplified example shows the basic idea. A complete example follows the formal specification of the framework:</p> | ||||
| <pre>struct C | ||||
| { | ||||
|    template<class InPlaceFactory> | ||||
|    C ( InPlaceFactory const& aFactoty ) | ||||
|     : | ||||
|     contained_ ( uninitialized_storage() ) | ||||
|    { | ||||
|      aFactory.template apply<X>(contained_); | ||||
|    } | ||||
|  | ||||
|   ~C()  | ||||
|   {  | ||||
|     contained_ -> X::~X(); | ||||
|     delete[] contained_ ;  | ||||
|   } | ||||
|  | ||||
|   char* uninitialized_storage() { return new char[sizeof(X)] ; } | ||||
|  | ||||
|   char* contained_ ; | ||||
| } ; | ||||
|  | ||||
| void foo() | ||||
| { | ||||
|   C c( in_place(123,"hello") ) ; | ||||
| } | ||||
| </pre> | ||||
|  | ||||
| <HR> | ||||
|  | ||||
| <H2><A NAME="specification">Specification</A></H2> | ||||
|  | ||||
| <p>The following is the first member of the family of 'in_place_factory' classes, along with its corresponding helper template function. | ||||
| The rest of the family varies only in the number and type of template (and constructor) parameters.</p> | ||||
| <PRE>namespace boost { | ||||
|  | ||||
| struct in_place_factory_base {} ; | ||||
|  | ||||
| template<class A0> | ||||
| class in_place_factory : public in_place_factory_base | ||||
| { | ||||
|   public:</PRE> | ||||
|  | ||||
| <PRE>    in_place_factory ( A0 const& a0 ) : m_a0(a0) {} | ||||
|  | ||||
|     template< class T > | ||||
|     void apply ( void* address ) const | ||||
|     { | ||||
|       new (address) T(m_a0); | ||||
|     } | ||||
|  | ||||
|   private:</PRE> | ||||
|  | ||||
| <PRE>    A0 const& m_a0 ; | ||||
| } ; | ||||
|  | ||||
| template<class A0> | ||||
| in_place_factory<A0> in_place ( A0 const& a0 ) | ||||
| { | ||||
|   return in_place_factory<A0>(a0); | ||||
| } | ||||
| </PRE> | ||||
|  | ||||
| <p>Similarly, the following is the first member of the family of 'typed_in_place_factory' classes, along with its corresponding | ||||
| helper template function. The rest of the family varies only in the number and type of template (and constructor) parameters.</p> | ||||
| <PRE>namespace boost { | ||||
|  | ||||
| struct typed_in_place_factory_base {} ; | ||||
|  | ||||
| template<class T, class A0> | ||||
| class typed_in_place_factory : public typed_in_place_factory_base | ||||
| { | ||||
|   public:</PRE> | ||||
|  | ||||
| <PRE>    typed_in_place_factory ( A0 const& a0 ) : m_a0(a0) {} | ||||
|  | ||||
|     void apply ( void* address ) const | ||||
|     { | ||||
|       new (address) T(m_a0); | ||||
|     } | ||||
|  | ||||
|   private:</PRE> | ||||
|  | ||||
| <PRE>    A0 const& m_a0 ; | ||||
| } ; | ||||
|  | ||||
| template<class T, class A0> | ||||
| typed_in_place_factory<A0> in_place ( A0 const& a0 ) | ||||
| { | ||||
|   return typed_in_place_factory<T,A0>(a0); | ||||
| }</PRE> | ||||
|  | ||||
| <PRE>} | ||||
| </PRE> | ||||
|  | ||||
| <p>As you can see, the 'in_place_factory' and 'typed_in_place_factory' template classes varies only in the way they specify | ||||
| the target type: in the first family, the type is given as a template argument to the apply member function while in the | ||||
| second it is given directly as part of the factory class.<br> | ||||
| When the container holds a unique non-polymorphic type (such as the case of Boost.Optional), it knows the exact dynamic-type | ||||
| of the contained object and can pass it to the apply() method of a (non-typed) factory. | ||||
| In this case, end users can use an 'in_place_factory' instance which can be constructed without the type of the object to construct.<br> | ||||
| However, if the container holds heterogeneous or polymorphic objects (such as the case of Boost.Variant), the dynamic-type | ||||
| of the object to be constructed must be known by the factory itslef. In this case, end users must use a 'typed_in_place_factory' | ||||
| instead.</p> | ||||
|  | ||||
| <HR> | ||||
|  | ||||
| <h2><A NAME="container-usage">Container-side Usage</a></h2> | ||||
|  | ||||
| <p>As shown in the introductory simplified example, the container class must | ||||
| contain methods that accept an instance of | ||||
| these factories and pass the object's storage to the factory's apply method.<br> | ||||
| However, the type of the factory class cannot be completly specified in the container class because that would | ||||
| defeat the whole purpose of the factories which is to allow the container to accept a variadic argument list | ||||
| for the constructor of its contained object.<br> | ||||
| The correct function overload must be based on the only distinctive and common | ||||
| characteristic of all the classes in each family, the base class.<br> | ||||
| Depending on the container class, you can use 'enable_if' to generate the right overload, or use the following | ||||
| dispatch technique (used in the Boost.Optional class): | ||||
| </p> | ||||
| <pre>struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|  | ||||
|    template<class Expr> | ||||
|    C ( Expr const& expr ) | ||||
|     : | ||||
|     contained_ ( uninitialized_storage() ) | ||||
|    { | ||||
|     construct(expr,&expr) | ||||
|    } | ||||
|  | ||||
|   ~C() { delete contained_ ; } | ||||
|  | ||||
|   template<class InPlaceFactory> | ||||
|   void construct ( InPlaceFactory const& aFactory, boost::in_place_factory_base* ) | ||||
|   { | ||||
|     aFactory.template apply<X>(contained_); | ||||
|   } | ||||
|  | ||||
|   template<class TypedInPlaceFactory> | ||||
|   void construct ( TypedInPlaceFactory const& aFactory, boost::typed_in_place_factory_base* ) | ||||
|   { | ||||
|     aFactory.apply(contained_); | ||||
|   } | ||||
|  | ||||
|   X* uninitialized_storage() { return static_cast<X*>(new char[sizeof(X)]) ; } | ||||
|  | ||||
|   X* contained_ ; | ||||
| } ; | ||||
| </pre> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <h2><A NAME="user-usage">User-side Usage</a></h2> | ||||
|  | ||||
| <p>End users pass to the container an instance of a factory object holding the actual parameters needed to construct the | ||||
| contained object directly within the container. For this, the helper template function 'in_place' is used.<br> | ||||
| The call 'in_place(a0,a1,a2,...,an)' constructs a (non-typed) 'in_place_factory' instance with the given argument list.<br> | ||||
| The call 'in_place<T>(a0,a1,a2,...,an)' constructs a 'typed_in_place_factory' instance with the given argument list for the | ||||
| type 'T'.</p> | ||||
| <pre>void foo() | ||||
| { | ||||
|   C a( in_place(123,"hello") ) ;    // in_place_factory passed | ||||
|   C b( in_place<X>(456,"world") ) ; // typed_in_place_factory passed | ||||
| } | ||||
| </pre> | ||||
|  | ||||
| <P>Revised September 17, 2004</P> | ||||
| <p><EFBFBD> Copyright Fernando Luis Cacciola Carballal, 2004</p> | ||||
| <p> Use, modification, and distribution are subject to the Boost Software | ||||
| License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt"> | ||||
| LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> | ||||
| www.boost.org/LICENSE_1_0.txt</a>)</p> | ||||
| <P>Developed by <A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A>, | ||||
| the latest version of this file can be found at <A | ||||
| HREF="http://www.boost.org">www.boost.org</A>, and the boost | ||||
| <A HREF="http://www.boost.org/more/mailing_lists.htm#main">discussion lists</A></P> | ||||
| </BODY> | ||||
| </HTML> | ||||
							
								
								
									
										50
									
								
								include/boost/assert.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								include/boost/assert.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // | ||||
| //  boost/assert.hpp - BOOST_ASSERT(expr) | ||||
| // | ||||
| //  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright (c) 2007 Peter Dimov | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| //  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> // .h to support old libraries w/o <cassert> - effect is the same | ||||
| # define BOOST_ASSERT(expr) assert(expr) | ||||
| #endif | ||||
|  | ||||
| #undef BOOST_VERIFY | ||||
|  | ||||
| #if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) | ||||
|  | ||||
| # define BOOST_VERIFY(expr) ((void)(expr)) | ||||
|  | ||||
| #else | ||||
|  | ||||
| # define BOOST_VERIFY(expr) BOOST_ASSERT(expr) | ||||
|  | ||||
| #endif | ||||
| @@ -1,9 +1,10 @@ | ||||
| //  (C) Copyright Boost.org 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. | ||||
| //  (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 http://www.boost.org for most recent version including documentation. | ||||
| //  See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp | ||||
| //  for full copyright notices. | ||||
|  | ||||
|   | ||||
							
								
								
									
										69
									
								
								include/boost/checked_delete.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								include/boost/checked_delete.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| #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) 2002, 2003 Peter Dimov | ||||
| //  Copyright (c) 2003 Daniel Frey | ||||
| //  Copyright (c) 2003 Howard Hinnant | ||||
| // | ||||
| //  Distributed under the Boost Software License, Version 1.0. (See | ||||
| //  accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| //  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 | ||||
| @@ -1,9 +1,10 @@ | ||||
| //  (C) Copyright Boost.org 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. | ||||
| //  (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 http://www.boost.org for most recent version including documentation. | ||||
| //  See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp | ||||
| //  for full copyright notices. | ||||
|  | ||||
|   | ||||
							
								
								
									
										67
									
								
								include/boost/current_function.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								include/boost/current_function.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| #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. | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| //  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(__DMC__) && (__DMC__ >= 0x810) | ||||
|  | ||||
| # 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 | ||||
| @@ -1,10 +1,9 @@ | ||||
| //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 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. | ||||
|  | ||||
| //  See http://www.boost.org for most recent version including documentation. | ||||
| //  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) | ||||
| @@ -22,34 +21,44 @@ | ||||
| #ifndef BOOST_CONFIG_HPP | ||||
| #include <boost/config.hpp> | ||||
| #endif | ||||
| #include <cstddef> | ||||
|  | ||||
| #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 | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
| #include <boost/type_traits/is_pointer.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
|  | ||||
| namespace boost{ | ||||
|  | ||||
| namespace detail{ | ||||
|  | ||||
| template <typename T, bool isp, bool b1, bool b2> | ||||
| 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, true> | ||||
| struct ct_imp<T, isp, true> | ||||
| { | ||||
|    typedef T const param_type; | ||||
|    typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type; | ||||
| }; | ||||
|  | ||||
| template <typename T, bool b1, bool b2> | ||||
| struct ct_imp<T, true, b1, b2> | ||||
| template <typename T, bool b1> | ||||
| struct ct_imp<T, true, b1> | ||||
| { | ||||
|    typedef T const param_type; | ||||
|    typedef const T param_type; | ||||
| }; | ||||
|  | ||||
| } | ||||
| @@ -67,7 +76,11 @@ public: | ||||
|    // 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<typename remove_const<T>::type>::value, ::boost::is_arithmetic<typename remove_const<T>::type>::value, sizeof(T) <= sizeof(void*)>::param_type param_type; | ||||
|    typedef typename boost::detail::ct_imp< | ||||
|       T, | ||||
|       ::boost::is_pointer<T>::value, | ||||
|       ::boost::is_arithmetic<T>::value | ||||
|    >::param_type param_type; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| @@ -79,7 +92,7 @@ struct call_traits<T&> | ||||
|    typedef T& param_type;  // hh removed const | ||||
| }; | ||||
|  | ||||
| #if defined(__BORLANDC__) && (__BORLANDC__ <= 0x551) | ||||
| #if BOOST_WORKAROUND( __BORLANDC__,  < 0x5A0 ) | ||||
| // 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 | ||||
| @@ -108,8 +121,17 @@ struct call_traits<T&const volatile> | ||||
|    typedef const T& const_reference; | ||||
|    typedef T& param_type;  // hh removed const | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| template <typename T> | ||||
| struct call_traits< T * > | ||||
| { | ||||
|    typedef T * value_type; | ||||
|    typedef T * & reference; | ||||
|    typedef T * const & const_reference; | ||||
|    typedef T * const 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]> | ||||
| { | ||||
| @@ -135,6 +157,7 @@ public: | ||||
|    typedef const array_type& const_reference; | ||||
|    typedef const T* const param_type; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,14 +1,16 @@ | ||||
| //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 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. | ||||
|  | ||||
| //  See http://www.boost.org for most recent version including documentation. | ||||
| //  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 | ||||
| @@ -19,19 +21,23 @@ | ||||
| #define BOOST_DETAIL_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 | ||||
|  | ||||
| #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> | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| # pragma warning(push) | ||||
| # pragma warning(disable:4512) | ||||
| #endif  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| template <class T1, class T2> | ||||
| class compressed_pair; | ||||
|  | ||||
|  | ||||
| // compressed_pair | ||||
|  | ||||
| namespace details | ||||
| @@ -104,10 +110,10 @@ namespace details | ||||
|       compressed_pair_imp(first_param_type x, second_param_type y) | ||||
|          : first_(x), second_(y) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(first_param_type x) | ||||
|       compressed_pair_imp(first_param_type x) | ||||
|          : first_(x) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(second_param_type y) | ||||
|       compressed_pair_imp(second_param_type y) | ||||
|          : second_(y) {} | ||||
|  | ||||
|       first_reference       first()       {return first_;} | ||||
| @@ -116,10 +122,10 @@ namespace details | ||||
|       second_reference       second()       {return second_;} | ||||
|       second_const_reference second() const {return second_;} | ||||
|  | ||||
|       void swap(compressed_pair_imp& y) | ||||
|       void swap(::boost::compressed_pair<T1, T2>& y) | ||||
|       { | ||||
|          cp_swap(first_, y.first_); | ||||
|          cp_swap(second_, y.second_); | ||||
|          cp_swap(first_, y.first()); | ||||
|          cp_swap(second_, y.second()); | ||||
|       } | ||||
|    private: | ||||
|       first_type first_; | ||||
| @@ -130,7 +136,7 @@ namespace details | ||||
|  | ||||
|    template <class T1, class T2> | ||||
|    class compressed_pair_imp<T1, T2, 1> | ||||
|       : private T1 | ||||
|       : protected ::boost::remove_cv<T1>::type | ||||
|    { | ||||
|    public: | ||||
|       typedef T1                                                 first_type; | ||||
| @@ -147,10 +153,10 @@ namespace details | ||||
|       compressed_pair_imp(first_param_type x, second_param_type y) | ||||
|          : first_type(x), second_(y) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(first_param_type x) | ||||
|       compressed_pair_imp(first_param_type x) | ||||
|          : first_type(x) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(second_param_type y) | ||||
|       compressed_pair_imp(second_param_type y) | ||||
|          : second_(y) {} | ||||
|  | ||||
|       first_reference       first()       {return *this;} | ||||
| @@ -159,10 +165,10 @@ namespace details | ||||
|       second_reference       second()       {return second_;} | ||||
|       second_const_reference second() const {return second_;} | ||||
|  | ||||
|       void swap(compressed_pair_imp& y) | ||||
|       void swap(::boost::compressed_pair<T1,T2>& y) | ||||
|       { | ||||
|          // no need to swap empty base class: | ||||
|          cp_swap(second_, y.second_); | ||||
|          cp_swap(second_, y.second()); | ||||
|       } | ||||
|    private: | ||||
|       second_type second_; | ||||
| @@ -172,7 +178,7 @@ namespace details | ||||
|  | ||||
|    template <class T1, class T2> | ||||
|    class compressed_pair_imp<T1, T2, 2> | ||||
|       : private T2 | ||||
|       : protected ::boost::remove_cv<T2>::type | ||||
|    { | ||||
|    public: | ||||
|       typedef T1                                                 first_type; | ||||
| @@ -189,10 +195,10 @@ namespace details | ||||
|       compressed_pair_imp(first_param_type x, second_param_type y) | ||||
|          : second_type(y), first_(x) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(first_param_type x) | ||||
|       compressed_pair_imp(first_param_type x) | ||||
|          : first_(x) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(second_param_type y) | ||||
|       compressed_pair_imp(second_param_type y) | ||||
|          : second_type(y) {} | ||||
|  | ||||
|       first_reference       first()       {return first_;} | ||||
| @@ -201,10 +207,10 @@ namespace details | ||||
|       second_reference       second()       {return *this;} | ||||
|       second_const_reference second() const {return *this;} | ||||
|  | ||||
|       void swap(compressed_pair_imp& y) | ||||
|       void swap(::boost::compressed_pair<T1,T2>& y) | ||||
|       { | ||||
|          // no need to swap empty base class: | ||||
|          cp_swap(first_, y.first_); | ||||
|          cp_swap(first_, y.first()); | ||||
|       } | ||||
|  | ||||
|    private: | ||||
| @@ -215,8 +221,8 @@ namespace details | ||||
|  | ||||
|    template <class T1, class T2> | ||||
|    class compressed_pair_imp<T1, T2, 3> | ||||
|       : private T1, | ||||
|         private T2 | ||||
|       : protected ::boost::remove_cv<T1>::type, | ||||
|         protected ::boost::remove_cv<T2>::type | ||||
|    { | ||||
|    public: | ||||
|       typedef T1                                                 first_type; | ||||
| @@ -233,10 +239,10 @@ namespace details | ||||
|       compressed_pair_imp(first_param_type x, second_param_type y) | ||||
|          : first_type(x), second_type(y) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(first_param_type x) | ||||
|       compressed_pair_imp(first_param_type x) | ||||
|          : first_type(x) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(second_param_type y) | ||||
|       compressed_pair_imp(second_param_type y) | ||||
|          : second_type(y) {} | ||||
|  | ||||
|       first_reference       first()       {return *this;} | ||||
| @@ -246,16 +252,19 @@ namespace details | ||||
|       second_const_reference second() const {return *this;} | ||||
|       // | ||||
|       // no need to swap empty bases: | ||||
|       void swap(compressed_pair_imp&) {} | ||||
|       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(). | ||||
|    //      Originally this did not store an instance of T2 at all | ||||
|    //      but that led to problems beause it meant &x.first() == &x.second() | ||||
|    //      which is not true for any other kind of pair, so now we store an instance | ||||
|    //      of T2 just in case the user is relying on first() and second() returning | ||||
|    //      different objects (albeit both empty). | ||||
|    template <class T1, class T2> | ||||
|    class compressed_pair_imp<T1, T2, 4> | ||||
|       : private T1 | ||||
|       : protected ::boost::remove_cv<T1>::type | ||||
|    { | ||||
|    public: | ||||
|       typedef T1                                                 first_type; | ||||
| @@ -269,20 +278,21 @@ namespace details | ||||
|  | ||||
|       compressed_pair_imp() {} | ||||
|  | ||||
|       compressed_pair_imp(first_param_type x, second_param_type) | ||||
|          : first_type(x) {} | ||||
|       compressed_pair_imp(first_param_type x, second_param_type y) | ||||
|          : first_type(x), m_second(y) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(first_param_type x) | ||||
|          : first_type(x) {} | ||||
|       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 *this;} | ||||
|       second_const_reference second() const {return *this;} | ||||
|       second_reference       second()       {return m_second;} | ||||
|       second_const_reference second() const {return m_second;} | ||||
|  | ||||
|       void swap(compressed_pair_imp&) {} | ||||
|       void swap(::boost::compressed_pair<T1,T2>&) {} | ||||
|    private: | ||||
|       T2 m_second; | ||||
|    }; | ||||
|  | ||||
|    // 5    T1 == T2 and are not empty:   //JM | ||||
| @@ -305,7 +315,7 @@ namespace details | ||||
|       compressed_pair_imp(first_param_type x, second_param_type y) | ||||
|          : first_(x), second_(y) {} | ||||
|  | ||||
|       explicit compressed_pair_imp(first_param_type x) | ||||
|       compressed_pair_imp(first_param_type x) | ||||
|          : first_(x), second_(x) {} | ||||
|  | ||||
|       first_reference       first()       {return first_;} | ||||
| @@ -314,10 +324,10 @@ namespace details | ||||
|       second_reference       second()       {return second_;} | ||||
|       second_const_reference second() const {return second_;} | ||||
|  | ||||
|       void swap(compressed_pair_imp<T1, T2, 5>& y) | ||||
|       void swap(::boost::compressed_pair<T1, T2>& y) | ||||
|       { | ||||
|          cp_swap(first_, y.first_); | ||||
|          cp_swap(second_, y.second_); | ||||
|          cp_swap(first_, y.first()); | ||||
|          cp_swap(second_, y.second()); | ||||
|       } | ||||
|    private: | ||||
|       first_type first_; | ||||
| @@ -401,7 +411,10 @@ public: | ||||
|  | ||||
|             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) {} | ||||
| #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();} | ||||
| @@ -409,7 +422,7 @@ public: | ||||
|    second_reference       second()       {return base::second();} | ||||
|    second_const_reference second() const {return base::second();} | ||||
|  | ||||
|    void swap(compressed_pair& y) { base::swap(y); } | ||||
|    void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); } | ||||
| }; | ||||
|  | ||||
| template <class T1, class T2> | ||||
| @@ -422,7 +435,9 @@ swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y) | ||||
|  | ||||
| } // boost | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| # pragma warning(pop) | ||||
| #endif  | ||||
|  | ||||
| #endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,9 @@ | ||||
| //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 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. | ||||
|  | ||||
| //  See http://www.boost.org for most recent version including documentation. | ||||
| //  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 | ||||
| @@ -33,7 +32,7 @@ | ||||
|  | ||||
| namespace boost{ | ||||
|  | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) | ||||
| #ifdef BOOST_MSVC6_MEMBER_TEMPLATES | ||||
| // | ||||
| // use member templates to emulate | ||||
| // partial specialisation: | ||||
| @@ -64,7 +63,8 @@ struct reference_call_traits | ||||
|    typedef T const_reference; | ||||
|    typedef T param_type; | ||||
| }; | ||||
| template <bool simple, bool reference> | ||||
|  | ||||
| template <bool pointer, bool arithmetic, bool reference> | ||||
| struct call_traits_chooser | ||||
| { | ||||
|    template <class T> | ||||
| @@ -73,8 +73,9 @@ struct call_traits_chooser | ||||
|       typedef standard_call_traits<T> type; | ||||
|    }; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct call_traits_chooser<true, false> | ||||
| struct call_traits_chooser<true, false, false> | ||||
| { | ||||
|    template <class T> | ||||
|    struct rebind | ||||
| @@ -82,8 +83,9 @@ struct call_traits_chooser<true, false> | ||||
|       typedef simple_call_traits<T> type; | ||||
|    }; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct call_traits_chooser<false, true> | ||||
| struct call_traits_chooser<false, false, true> | ||||
| { | ||||
|    template <class T> | ||||
|    struct rebind | ||||
| @@ -91,12 +93,50 @@ struct call_traits_chooser<false, true> | ||||
|       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<(is_pointer<T>::value || is_arithmetic<T>::value) && sizeof(T) <= sizeof(void*), is_reference<T>::value> chooser; | ||||
|     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: | ||||
|   | ||||
| @@ -1,17 +1,16 @@ | ||||
| //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 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. | ||||
|  | ||||
| //  See http://www.boost.org for most recent version including documentation. | ||||
| //  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. | ||||
|    07 Oct 2000: | ||||
|       Added better single argument constructor support. | ||||
|    03 Oct 2000: | ||||
|       Added VC6 support (JM). | ||||
|    23rd July 2000: | ||||
| @@ -38,7 +37,7 @@ | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) | ||||
| #ifdef BOOST_MSVC6_MEMBER_TEMPLATES | ||||
| // | ||||
| // use member templates to emulate | ||||
| // partial specialisation.  Note that due to | ||||
| @@ -168,7 +167,7 @@ public: | ||||
|    compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x) | ||||
|       : T2(x.second()), _first(x.first()) {} | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| #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. | ||||
| @@ -293,22 +292,24 @@ public: | ||||
|    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) : T1(x) {} | ||||
|             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) {} | ||||
|    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()){} | ||||
|       : T1(x.first()), m_second(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; } | ||||
|    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 | ||||
|   | ||||
							
								
								
									
										17
									
								
								include/boost/exception.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								include/boost/exception.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| //Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc. | ||||
|  | ||||
| //Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
| //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| #ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492 | ||||
| #define UUID_1D94A7C6054E11DB9804B622A1EF5492 | ||||
|  | ||||
| #include <boost/exception/diagnostic_information.hpp> | ||||
| #include <boost/exception/error_info.hpp> | ||||
| #include <boost/exception/exception.hpp> | ||||
| #include <boost/exception/get_error_info.hpp> | ||||
| #include <boost/exception/info.hpp> | ||||
| #include <boost/exception/info_tuple.hpp> | ||||
| #include <boost/exception_ptr.hpp> | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										80
									
								
								include/boost/generator_iterator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								include/boost/generator_iterator.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| // (C) Copyright Jens Maurer 2001. | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| // 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 | ||||
|  | ||||
							
								
								
									
										51
									
								
								include/boost/next_prior.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								include/boost/next_prior.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| //  Boost next_prior.hpp header file  ---------------------------------------// | ||||
|  | ||||
| //  (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. Distributed under the Boost | ||||
| //  Software License, Version 1.0. (See accompanying file | ||||
| //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  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 | ||||
							
								
								
									
										36
									
								
								include/boost/noncopyable.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								include/boost/noncopyable.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| //  Boost noncopyable.hpp header file  --------------------------------------// | ||||
|  | ||||
| //  (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost | ||||
| //  Software License, Version 1.0. (See accompanying file | ||||
| //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  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 | ||||
|  | ||||
| namespace noncopyable_  // protection from unintended ADL | ||||
| { | ||||
|   class noncopyable | ||||
|   { | ||||
|    protected: | ||||
|       noncopyable() {} | ||||
|       ~noncopyable() {} | ||||
|    private:  // emphasize the following members are private | ||||
|       noncopyable( const noncopyable& ); | ||||
|       const noncopyable& operator=( const noncopyable& ); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| typedef noncopyable_::noncopyable noncopyable; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // BOOST_NONCOPYABLE_HPP_INCLUDED | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										178
									
								
								include/boost/ref.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								include/boost/ref.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | ||||
| #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> | ||||
| #include <boost/detail/workaround.hpp> | ||||
|  | ||||
| // | ||||
| //  ref.hpp - ref/cref, useful helper functions | ||||
| // | ||||
| //  Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) | ||||
| //  Copyright (C) 2001, 2002 Peter Dimov | ||||
| //  Copyright (C) 2002 David Abrahams | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| //  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_WORKAROUND( 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__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) | ||||
| #  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 unwrap_reference | ||||
| { | ||||
|  public: | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| #  define AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(X) \ | ||||
| template<typename T> \ | ||||
| class is_reference_wrapper< X > \ | ||||
|     : public mpl::true_ \ | ||||
| { \ | ||||
| }; \ | ||||
| \ | ||||
| template<typename T> \ | ||||
| class unwrap_reference< X > \ | ||||
| { \ | ||||
|  public: \ | ||||
|     typedef T type; \ | ||||
| }; \ | ||||
| /**/ | ||||
|  | ||||
| AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T>) | ||||
| #if !defined(BOOST_NO_CV_SPECIALIZATIONS) | ||||
| AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const) | ||||
| AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> volatile) | ||||
| AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const volatile) | ||||
| #endif | ||||
|  | ||||
| #  undef AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF | ||||
|  | ||||
| # 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 | ||||
| @@ -1,96 +1,20 @@ | ||||
| //  boost utility.hpp header file  -------------------------------------------// | ||||
| //  Boost utility.hpp header file  -------------------------------------------// | ||||
|  | ||||
| //  (C) Copyright boost.org 1999. 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. | ||||
| //  Copyright 1999-2003 Aleksey Gurtovoy.  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 for most recent version including documentation. | ||||
|  | ||||
| //  Classes appear in alphabetical order | ||||
|  | ||||
| //  Revision History | ||||
| //  26 Jan 00  protected noncopyable destructor added (Miki Jovanovic) | ||||
| //  10 Dec 99  next() and prior() templates added (Dave Abrahams) | ||||
| //  30 Aug 99  moved cast templates to cast.hpp (Beman Dawes) | ||||
| //   3 Aug 99  cast templates added | ||||
| //  20 Jul 99  name changed to utility.hpp  | ||||
| //   9 Jun 99  protected noncopyable default ctor | ||||
| //   2 Jun 99  Initial Version. Class noncopyable only contents (Dave Abrahams) | ||||
| //  See <http://www.boost.org/libs/utility/> for the library's home page. | ||||
|  | ||||
| #ifndef BOOST_UTILITY_HPP | ||||
| #define BOOST_UTILITY_HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <cstddef>            // for size_t | ||||
| #include <utility>            // for std::pair | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| //  next() and prior() template functions  -----------------------------------// | ||||
|  | ||||
|     //  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); | ||||
|  | ||||
|     //  Contributed by Dave Abrahams | ||||
|  | ||||
|     template <class T> | ||||
|     T next(T x) { return ++x; } | ||||
|  | ||||
|     template <class T> | ||||
|     T prior(T x) { return --x; } | ||||
|  | ||||
|  | ||||
| //  class noncopyable  -------------------------------------------------------// | ||||
|  | ||||
|     //  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& ); | ||||
|     }; // noncopyable | ||||
|  | ||||
| //  class tied  -------------------------------------------------------// | ||||
|  | ||||
|     // A helper for conveniently assigning the two values from a pair | ||||
|     // into separate variables. The idea for this comes from Jaakko J<>rvi's | ||||
|     // Binder/Lambda Library. | ||||
|  | ||||
|     // Constributed by Jeremy Siek | ||||
|  | ||||
|     template <class A, class B> | ||||
|     class tied { | ||||
|     public: | ||||
|       inline tied(A& a, B& b) : _a(a), _b(b) { } | ||||
|       template <class U, class V> | ||||
|       inline tied& operator=(const std::pair<U,V>& p) { | ||||
|         _a = p.first; | ||||
|         _b = p.second; | ||||
|         return *this; | ||||
|       } | ||||
|     protected: | ||||
|       A& _a; | ||||
|       B& _b; | ||||
|     }; | ||||
|  | ||||
|     template <class A, class B> | ||||
|     inline tied<A,B> tie(A& a, B& b) { return tied<A,B>(a, b); } | ||||
|  | ||||
| } // namespace boost | ||||
| #include <boost/utility/addressof.hpp> | ||||
| #include <boost/utility/base_from_member.hpp> | ||||
| #include <boost/utility/binary.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 | ||||
|  | ||||
|   | ||||
							
								
								
									
										63
									
								
								include/boost/utility/addressof.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								include/boost/utility/addressof.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| // Copyright (C) 2002 Brad King (brad.king@kitware.com)  | ||||
| //                    Douglas Gregor (gregod@cs.rpi.edu) | ||||
| // | ||||
| // Copyright (C) 2002, 2008 Peter Dimov | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| // 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> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| template<class T> struct addressof_impl | ||||
| { | ||||
|     static inline T * f( T & v, long ) | ||||
|     { | ||||
|         return reinterpret_cast<T*>( | ||||
|             &const_cast<char&>(reinterpret_cast<const volatile char &>(v))); | ||||
|     } | ||||
|  | ||||
|     static inline T * f( T * v, int ) | ||||
|     { | ||||
|         return v; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| template<class T> T * addressof( T & v ) | ||||
| { | ||||
|     return boost::detail::addressof_impl<T>::f( v, 0 ); | ||||
| } | ||||
|  | ||||
| // Borland doesn't like casting an array reference to a char reference | ||||
| // but these overloads work around the problem. | ||||
| # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) | ||||
| template<typename T,std::size_t N> | ||||
| T (*addressof(T (&t)[N]))[N] | ||||
| { | ||||
|    return reinterpret_cast<T(*)[N]>(&t); | ||||
| } | ||||
|  | ||||
| template<typename T,std::size_t N> | ||||
| const T (*addressof(const T (&t)[N]))[N] | ||||
| { | ||||
|    return reinterpret_cast<const T(*)[N]>(&t); | ||||
| } | ||||
| # endif | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // BOOST_UTILITY_ADDRESSOF_HPP | ||||
							
								
								
									
										87
									
								
								include/boost/utility/base_from_member.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								include/boost/utility/base_from_member.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| //  boost utility/base_from_member.hpp header file  --------------------------// | ||||
|  | ||||
| //  Copyright 2001, 2003, 2004 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/preprocessor/arithmetic/inc.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_binary_params.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_params.hpp> | ||||
| #include <boost/preprocessor/repetition/repeat_from_to.hpp> | ||||
|  | ||||
|  | ||||
| //  Base-from-member arity configuration macro  ------------------------------// | ||||
|  | ||||
| // The following macro determines how many arguments will be in the largest | ||||
| // constructor template of base_from_member.  Constructor templates will be | ||||
| // generated from one argument to this maximum.  Code from other files can read | ||||
| // this number if they need to always match the exact maximum base_from_member | ||||
| // uses.  The maximum constructor length can be changed by overriding the | ||||
| // #defined constant.  Make sure to apply the override, if any, for all source | ||||
| // files during project compiling for consistency. | ||||
|  | ||||
| // Contributed by Jonathan Turkanis | ||||
|  | ||||
| #ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY | ||||
| #define BOOST_BASE_FROM_MEMBER_MAX_ARITY  10 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| //  An iteration of a constructor template for base_from_member  -------------// | ||||
|  | ||||
| // A macro that should expand to: | ||||
| //     template < typename T1, ..., typename Tn > | ||||
| //     base_from_member( T1 x1, ..., Tn xn ) | ||||
| //         : member( x1, ..., xn ) | ||||
| //         {} | ||||
| // This macro should only persist within this file. | ||||
|  | ||||
| #define BOOST_PRIVATE_CTR_DEF( z, n, data )                            \ | ||||
|     template < BOOST_PP_ENUM_PARAMS(n, typename T) >                   \ | ||||
|     explicit base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) )  \ | ||||
|         : member( BOOST_PP_ENUM_PARAMS(n, x) )                         \ | ||||
|         {}                                                             \ | ||||
|     /**/ | ||||
|  | ||||
|  | ||||
| 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 = 0 > | ||||
| class base_from_member | ||||
| { | ||||
| protected: | ||||
|     MemberType  member; | ||||
|  | ||||
|     base_from_member() | ||||
|         : member() | ||||
|         {} | ||||
|  | ||||
|     BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY), | ||||
|      BOOST_PRIVATE_CTR_DEF, _ ) | ||||
|  | ||||
| };  // boost::base_from_member | ||||
|  | ||||
| }  // namespace boost | ||||
|  | ||||
|  | ||||
| // Undo any private macros | ||||
| #undef BOOST_PRIVATE_CTR_DEF | ||||
|  | ||||
|  | ||||
| #endif  // BOOST_UTILITY_BASE_FROM_MEMBER_HPP | ||||
							
								
								
									
										708
									
								
								include/boost/utility/binary.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										708
									
								
								include/boost/utility/binary.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,708 @@ | ||||
| /*============================================================================= | ||||
|     Copyright (c) 2005 Matthew Calabrese | ||||
|  | ||||
|     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) | ||||
| ==============================================================================*/ | ||||
|  | ||||
| #ifndef BOOST_UTILITY_BINARY_HPP | ||||
| #define BOOST_UTILITY_BINARY_HPP | ||||
|  | ||||
| /*============================================================================= | ||||
|  | ||||
|     Binary Literal Utility | ||||
|     ______________________ | ||||
|  | ||||
|  | ||||
|     The following code works by converting the input bit pattern into a | ||||
|     Boost.Preprocessor sequence, then converting groupings of 3 bits each into | ||||
|     the corresponding octal digit, and finally concatenating all of the digits | ||||
|     together along with a leading zero. This yields a standard octal literal | ||||
|     with the desired value as specified in bits. | ||||
|  | ||||
| ==============================================================================*/ | ||||
|  | ||||
| #include <boost/preprocessor/control/deduce_d.hpp> | ||||
| #include <boost/preprocessor/facilities/identity.hpp> | ||||
| #include <boost/preprocessor/cat.hpp> | ||||
| #include <boost/preprocessor/seq/cat.hpp> | ||||
| #include <boost/preprocessor/seq/transform.hpp> | ||||
| #include <boost/preprocessor/arithmetic/mod.hpp> | ||||
| #include <boost/preprocessor/seq/size.hpp> | ||||
| #include <boost/preprocessor/facilities/empty.hpp> | ||||
| #include <boost/preprocessor/control/while.hpp> | ||||
|  | ||||
| #define BOOST_BINARY( bit_groupings )                                          \ | ||||
|   BOOST_BINARY_LITERAL_D( BOOST_PP_DEDUCE_D(), bit_groupings )  | ||||
|  | ||||
| #define BOOST_BINARY_U( bit_groupings )                                        \ | ||||
|   BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, U )  | ||||
|  | ||||
| #define BOOST_BINARY_L( bit_groupings )                                        \ | ||||
|   BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, L )  | ||||
|  | ||||
| #define BOOST_BINARY_UL( bit_groupings )                                       \ | ||||
|   BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, UL )  | ||||
|  | ||||
| #define BOOST_BINARY_LU( bit_groupings )                                       \ | ||||
|   BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LU )  | ||||
|  | ||||
| #define BOOST_BINARY_LL( bit_groupings )                                       \ | ||||
|   BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LL )  | ||||
|  | ||||
| #define BOOST_BINARY_ULL( bit_groupings )                                      \ | ||||
|   BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, ULL )  | ||||
|  | ||||
| #define BOOST_BINARY_LLU( bit_groupings )                                      \ | ||||
|   BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LLU )  | ||||
|  | ||||
| #define BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, suffix )                 \ | ||||
|   BOOST_SUFFIXED_BINARY_LITERAL_D( BOOST_PP_DEDUCE_D(), bit_groupings, suffix )  | ||||
|  | ||||
| #define BOOST_SUFFIXED_BINARY_LITERAL_D( d, bit_groupings, suffix )            \ | ||||
|   BOOST_PP_CAT( BOOST_BINARY_LITERAL_D( d, bit_groupings ), suffix )  | ||||
|  | ||||
| #define BOOST_BINARY_LITERAL_D( d, bit_groupings )                             \ | ||||
|   BOOST_PP_SEQ_CAT                                                             \ | ||||
|   ( (0) BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings )  \ | ||||
|   )  | ||||
|  | ||||
| #define BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings )  \ | ||||
|   BOOST_PP_SEQ_TRANSFORM                                                       \ | ||||
|   ( BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION                                     \ | ||||
|   , BOOST_PP_NIL                                                               \ | ||||
|   , BOOST_PP_IDENTITY( BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_TRIPLE_SEQUENCE )()\ | ||||
|     ( BOOST_DETAIL_COMPLETE_TRIPLE_SEQUENCE                                    \ | ||||
|       (                                                                        \ | ||||
|         d                                                                      \ | ||||
|       , BOOST_DETAIL_CREATE_BINARY_LITERAL_BIT_SEQUENCE( d, bit_groupings )    \ | ||||
|       )                                                                        \ | ||||
|     )                                                                          \ | ||||
|   )  | ||||
|  | ||||
| #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_TRIPLE_SEQUENCE( bit_sequence )   \ | ||||
|   BOOST_PP_CAT                                                                 \ | ||||
|   ( BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1 bit_sequence      \ | ||||
|   , END_BIT                                                                    \ | ||||
|   )  | ||||
|  | ||||
| #define BOOST_DETAIL_BITS_PER_OCTIT 3 | ||||
|  | ||||
| #define BOOST_DETAIL_COMPLETE_TRIPLE_SEQUENCE( d, incomplete_nibble_sequence ) \ | ||||
|   BOOST_PP_CAT                                                                 \ | ||||
|   ( BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_                            \ | ||||
|   , BOOST_PP_MOD_D( d                                                          \ | ||||
|                   , BOOST_PP_SEQ_SIZE( incomplete_nibble_sequence )            \ | ||||
|                   , BOOST_DETAIL_BITS_PER_OCTIT                                \ | ||||
|                   )                                                            \ | ||||
|   )                                                                            \ | ||||
|   incomplete_nibble_sequence  | ||||
|  | ||||
| #define BOOST_DETAIL_FIXED_COMPL( bit )                                        \ | ||||
|   BOOST_PP_CAT( BOOST_DETAIL_FIXED_COMPL_, bit ) | ||||
|  | ||||
| #define BOOST_DETAIL_FIXED_COMPL_0 1  | ||||
|  | ||||
| #define BOOST_DETAIL_FIXED_COMPL_1 0  | ||||
|  | ||||
| #define BOOST_DETAIL_CREATE_BINARY_LITERAL_BIT_SEQUENCE( d, bit_groupings )    \ | ||||
|   BOOST_PP_EMPTY                                                               \ | ||||
|   BOOST_PP_CAT( BOOST_PP_WHILE_, d )                                           \ | ||||
|   ( BOOST_DETAIL_BINARY_LITERAL_PREDICATE                                      \ | ||||
|   , BOOST_DETAIL_BINARY_LITERAL_OPERATION                                      \ | ||||
|   , bit_groupings ()                                                           \ | ||||
|   )  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_PREDICATE( d, state )                      \ | ||||
|   BOOST_DETAIL_FIXED_COMPL( BOOST_DETAIL_IS_NULLARY_ARGS( state ) )  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_OPERATION( d, state )                      \ | ||||
|   BOOST_DETAIL_SPLIT_AND_SWAP                                                  \ | ||||
|   ( BOOST_PP_CAT( BOOST_DETAIL_BINARY_LITERAL_ELEMENT_, state ) )  | ||||
|  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION( s, dummy_param, tuple )        \ | ||||
|   BOOST_DETAIL_TERNARY_TRIPLE_TO_OCTAL tuple  | ||||
|  | ||||
| #define BOOST_DETAIL_TERNARY_TRIPLE_TO_OCTAL( bit2, bit1, bit0 )               \ | ||||
|   BOOST_DETAIL_TRIPLE_TO_OCTAL_ ## bit2 ## bit1 ## bit0  | ||||
|  | ||||
| #define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_1 (0)(0) | ||||
| #define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_2 (0) | ||||
| #define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_0   | ||||
|  | ||||
| #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1END_BIT   | ||||
|  | ||||
| #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1( bit )        \ | ||||
|   ( ( bit, BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_2  | ||||
|  | ||||
| #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_2( bit )        \ | ||||
|   bit, BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_3  | ||||
|  | ||||
| #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_3( bit )        \ | ||||
|   bit ) ) BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1  | ||||
|  | ||||
| #define BOOST_DETAIL_SPLIT_AND_SWAP( params )                                  \ | ||||
|   BOOST_PP_IDENTITY( BOOST_DETAIL_SPLIT_AND_SWAP_PARAMS )()( params ) | ||||
|  | ||||
| #define BOOST_DETAIL_SPLIT_AND_SWAP_PARAMS( first_param, second_param )        \ | ||||
|   second_param first_param  | ||||
|  | ||||
| #define BOOST_DETAIL_LEFT_OF_COMMA( params )                                   \ | ||||
|   BOOST_PP_IDENTITY( BOOST_DETAIL_FIRST_MACRO_PARAM )()( params )  | ||||
|  | ||||
| #define BOOST_DETAIL_FIRST_MACRO_PARAM( first_param, second_param )            \ | ||||
|   first_param  | ||||
|  | ||||
| /* Begin derived concepts from Chaos by Paul Mensonides */ | ||||
|  | ||||
| #define BOOST_DETAIL_IS_NULLARY_ARGS( param )                                  \ | ||||
|   BOOST_DETAIL_LEFT_OF_COMMA                                                   \ | ||||
|   ( BOOST_PP_CAT( BOOST_DETAIL_IS_NULLARY_ARGS_R_                              \ | ||||
|                 , BOOST_DETAIL_IS_NULLARY_ARGS_C param                         \ | ||||
|                 )                                                              \ | ||||
|   )  | ||||
|  | ||||
| #define BOOST_DETAIL_IS_NULLARY_ARGS_C()                                       \ | ||||
|   1  | ||||
|  | ||||
| #define BOOST_DETAIL_IS_NULLARY_ARGS_R_1                                       \ | ||||
|   1, BOOST_PP_NIL  | ||||
|  | ||||
| #define BOOST_DETAIL_IS_NULLARY_ARGS_R_BOOST_DETAIL_IS_NULLARY_ARGS_C          \ | ||||
|   0, BOOST_PP_NIL  | ||||
|  | ||||
| /* End derived concepts from Chaos by Paul Mensonides */ | ||||
|  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_000 0  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_001 1  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_010 2  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_011 3  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_100 4  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_101 5  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_110 6  | ||||
| #define BOOST_DETAIL_TRIPLE_TO_OCTAL_111 7  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0 (0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1 (1),  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00 (0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01 (0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10 (1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11 (1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00 (0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01 (0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10 (1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11 (1)(1),  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000 (0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001 (0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010 (0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011 (0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100 (1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101 (1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110 (1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111 (1)(1)(1),  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000 (0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001 (0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010 (0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011 (0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100 (0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101 (0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110 (0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111 (0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000 (1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001 (1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010 (1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011 (1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100 (1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101 (1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110 (1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111 (1)(1)(1)(1),  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000 (0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001 (0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010 (0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011 (0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100 (0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101 (0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110 (0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111 (0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000 (0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001 (0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010 (0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011 (0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100 (0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101 (0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110 (0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111 (0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000 (1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001 (1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010 (1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011 (1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100 (1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101 (1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110 (1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111 (1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000 (1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001 (1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010 (1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011 (1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100 (1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101 (1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110 (1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111 (1)(1)(1)(1)(1),  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000000 (0)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000001 (0)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000010 (0)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000011 (0)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000100 (0)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000101 (0)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000110 (0)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000111 (0)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001000 (0)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001001 (0)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001010 (0)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001011 (0)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001100 (0)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001101 (0)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001110 (0)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001111 (0)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010000 (0)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010001 (0)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010010 (0)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010011 (0)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010100 (0)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010101 (0)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010110 (0)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010111 (0)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011000 (0)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011001 (0)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011010 (0)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011011 (0)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011100 (0)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011101 (0)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011110 (0)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011111 (0)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100000 (1)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100001 (1)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100010 (1)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100011 (1)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100100 (1)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100101 (1)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100110 (1)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100111 (1)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101000 (1)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101001 (1)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101010 (1)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101011 (1)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101100 (1)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101101 (1)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101110 (1)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101111 (1)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110000 (1)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110001 (1)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110010 (1)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110011 (1)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110100 (1)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110101 (1)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110110 (1)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110111 (1)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111000 (1)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111001 (1)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111010 (1)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111011 (1)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111100 (1)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111101 (1)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111110 (1)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111111 (1)(1)(1)(1)(1)(1),  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000000 (0)(0)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000001 (0)(0)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000010 (0)(0)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000011 (0)(0)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000100 (0)(0)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000101 (0)(0)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000110 (0)(0)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000111 (0)(0)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001000 (0)(0)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001001 (0)(0)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001010 (0)(0)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001011 (0)(0)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001100 (0)(0)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001101 (0)(0)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001110 (0)(0)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001111 (0)(0)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010000 (0)(0)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010001 (0)(0)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010010 (0)(0)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010011 (0)(0)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010100 (0)(0)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010101 (0)(0)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010110 (0)(0)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010111 (0)(0)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011000 (0)(0)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011001 (0)(0)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011010 (0)(0)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011011 (0)(0)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011100 (0)(0)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011101 (0)(0)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011110 (0)(0)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011111 (0)(0)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100000 (0)(1)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100001 (0)(1)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100010 (0)(1)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100011 (0)(1)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100100 (0)(1)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100101 (0)(1)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100110 (0)(1)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100111 (0)(1)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101000 (0)(1)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101001 (0)(1)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101010 (0)(1)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101011 (0)(1)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101100 (0)(1)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101101 (0)(1)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101110 (0)(1)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101111 (0)(1)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110000 (0)(1)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110001 (0)(1)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110010 (0)(1)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110011 (0)(1)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110100 (0)(1)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110101 (0)(1)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110110 (0)(1)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110111 (0)(1)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111000 (0)(1)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111001 (0)(1)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111010 (0)(1)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111011 (0)(1)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111100 (0)(1)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111101 (0)(1)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111110 (0)(1)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111111 (0)(1)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000000 (1)(0)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000001 (1)(0)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000010 (1)(0)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000011 (1)(0)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000100 (1)(0)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000101 (1)(0)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000110 (1)(0)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000111 (1)(0)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001000 (1)(0)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001001 (1)(0)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001010 (1)(0)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001011 (1)(0)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001100 (1)(0)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001101 (1)(0)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001110 (1)(0)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001111 (1)(0)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010000 (1)(0)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010001 (1)(0)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010010 (1)(0)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010011 (1)(0)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010100 (1)(0)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010101 (1)(0)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010110 (1)(0)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010111 (1)(0)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011000 (1)(0)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011001 (1)(0)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011010 (1)(0)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011011 (1)(0)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011100 (1)(0)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011101 (1)(0)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011110 (1)(0)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011111 (1)(0)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100000 (1)(1)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100001 (1)(1)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100010 (1)(1)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100011 (1)(1)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100100 (1)(1)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100101 (1)(1)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100110 (1)(1)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100111 (1)(1)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101000 (1)(1)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101001 (1)(1)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101010 (1)(1)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101011 (1)(1)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101100 (1)(1)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101101 (1)(1)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101110 (1)(1)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101111 (1)(1)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110000 (1)(1)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110001 (1)(1)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110010 (1)(1)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110011 (1)(1)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110100 (1)(1)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110101 (1)(1)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110110 (1)(1)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110111 (1)(1)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111000 (1)(1)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111001 (1)(1)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111010 (1)(1)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111011 (1)(1)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111100 (1)(1)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111101 (1)(1)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111110 (1)(1)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111111 (1)(1)(1)(1)(1)(1)(1),  | ||||
|  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000000 (0)(0)(0)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000001 (0)(0)(0)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000010 (0)(0)(0)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000011 (0)(0)(0)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000100 (0)(0)(0)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000101 (0)(0)(0)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000110 (0)(0)(0)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000111 (0)(0)(0)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001000 (0)(0)(0)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001001 (0)(0)(0)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001010 (0)(0)(0)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001011 (0)(0)(0)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001100 (0)(0)(0)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001101 (0)(0)(0)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001110 (0)(0)(0)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001111 (0)(0)(0)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010000 (0)(0)(0)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010001 (0)(0)(0)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010010 (0)(0)(0)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010011 (0)(0)(0)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010100 (0)(0)(0)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010101 (0)(0)(0)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010110 (0)(0)(0)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010111 (0)(0)(0)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011000 (0)(0)(0)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011001 (0)(0)(0)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011010 (0)(0)(0)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011011 (0)(0)(0)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011100 (0)(0)(0)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011101 (0)(0)(0)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011110 (0)(0)(0)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011111 (0)(0)(0)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100000 (0)(0)(1)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100001 (0)(0)(1)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100010 (0)(0)(1)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100011 (0)(0)(1)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100100 (0)(0)(1)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100101 (0)(0)(1)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100110 (0)(0)(1)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100111 (0)(0)(1)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101000 (0)(0)(1)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101001 (0)(0)(1)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101010 (0)(0)(1)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101011 (0)(0)(1)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101100 (0)(0)(1)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101101 (0)(0)(1)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101110 (0)(0)(1)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101111 (0)(0)(1)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110000 (0)(0)(1)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110001 (0)(0)(1)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110010 (0)(0)(1)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110011 (0)(0)(1)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110100 (0)(0)(1)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110101 (0)(0)(1)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110110 (0)(0)(1)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110111 (0)(0)(1)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111000 (0)(0)(1)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111001 (0)(0)(1)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111010 (0)(0)(1)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111011 (0)(0)(1)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111100 (0)(0)(1)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111101 (0)(0)(1)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111110 (0)(0)(1)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111111 (0)(0)(1)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000000 (0)(1)(0)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000001 (0)(1)(0)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000010 (0)(1)(0)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000011 (0)(1)(0)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000100 (0)(1)(0)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000101 (0)(1)(0)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000110 (0)(1)(0)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000111 (0)(1)(0)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001000 (0)(1)(0)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001001 (0)(1)(0)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001010 (0)(1)(0)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001011 (0)(1)(0)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001100 (0)(1)(0)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001101 (0)(1)(0)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001110 (0)(1)(0)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001111 (0)(1)(0)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010000 (0)(1)(0)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010001 (0)(1)(0)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010010 (0)(1)(0)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010011 (0)(1)(0)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010100 (0)(1)(0)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010101 (0)(1)(0)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010110 (0)(1)(0)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010111 (0)(1)(0)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011000 (0)(1)(0)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011001 (0)(1)(0)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011010 (0)(1)(0)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011011 (0)(1)(0)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011100 (0)(1)(0)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011101 (0)(1)(0)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011110 (0)(1)(0)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011111 (0)(1)(0)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100000 (0)(1)(1)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100001 (0)(1)(1)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100010 (0)(1)(1)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100011 (0)(1)(1)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100100 (0)(1)(1)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100101 (0)(1)(1)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100110 (0)(1)(1)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100111 (0)(1)(1)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101000 (0)(1)(1)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101001 (0)(1)(1)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101010 (0)(1)(1)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101011 (0)(1)(1)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101100 (0)(1)(1)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101101 (0)(1)(1)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101110 (0)(1)(1)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101111 (0)(1)(1)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110000 (0)(1)(1)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110001 (0)(1)(1)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110010 (0)(1)(1)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110011 (0)(1)(1)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110100 (0)(1)(1)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110101 (0)(1)(1)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110110 (0)(1)(1)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110111 (0)(1)(1)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111000 (0)(1)(1)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111001 (0)(1)(1)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111010 (0)(1)(1)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111011 (0)(1)(1)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111100 (0)(1)(1)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111101 (0)(1)(1)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111110 (0)(1)(1)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111111 (0)(1)(1)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000000 (1)(0)(0)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000001 (1)(0)(0)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000010 (1)(0)(0)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000011 (1)(0)(0)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000100 (1)(0)(0)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000101 (1)(0)(0)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000110 (1)(0)(0)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000111 (1)(0)(0)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001000 (1)(0)(0)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001001 (1)(0)(0)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001010 (1)(0)(0)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001011 (1)(0)(0)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001100 (1)(0)(0)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001101 (1)(0)(0)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001110 (1)(0)(0)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001111 (1)(0)(0)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010000 (1)(0)(0)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010001 (1)(0)(0)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010010 (1)(0)(0)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010011 (1)(0)(0)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010100 (1)(0)(0)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010101 (1)(0)(0)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010110 (1)(0)(0)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010111 (1)(0)(0)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011000 (1)(0)(0)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011001 (1)(0)(0)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011010 (1)(0)(0)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011011 (1)(0)(0)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011100 (1)(0)(0)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011101 (1)(0)(0)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011110 (1)(0)(0)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011111 (1)(0)(0)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100000 (1)(0)(1)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100001 (1)(0)(1)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100010 (1)(0)(1)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100011 (1)(0)(1)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100100 (1)(0)(1)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100101 (1)(0)(1)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100110 (1)(0)(1)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100111 (1)(0)(1)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101000 (1)(0)(1)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101001 (1)(0)(1)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101010 (1)(0)(1)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101011 (1)(0)(1)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101100 (1)(0)(1)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101101 (1)(0)(1)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101110 (1)(0)(1)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101111 (1)(0)(1)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110000 (1)(0)(1)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110001 (1)(0)(1)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110010 (1)(0)(1)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110011 (1)(0)(1)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110100 (1)(0)(1)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110101 (1)(0)(1)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110110 (1)(0)(1)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110111 (1)(0)(1)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111000 (1)(0)(1)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111001 (1)(0)(1)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111010 (1)(0)(1)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111011 (1)(0)(1)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111100 (1)(0)(1)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111101 (1)(0)(1)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111110 (1)(0)(1)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111111 (1)(0)(1)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000000 (1)(1)(0)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000001 (1)(1)(0)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000010 (1)(1)(0)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000011 (1)(1)(0)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000100 (1)(1)(0)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000101 (1)(1)(0)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000110 (1)(1)(0)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000111 (1)(1)(0)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001000 (1)(1)(0)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001001 (1)(1)(0)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001010 (1)(1)(0)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001011 (1)(1)(0)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001100 (1)(1)(0)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001101 (1)(1)(0)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001110 (1)(1)(0)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001111 (1)(1)(0)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010000 (1)(1)(0)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010001 (1)(1)(0)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010010 (1)(1)(0)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010011 (1)(1)(0)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010100 (1)(1)(0)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010101 (1)(1)(0)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010110 (1)(1)(0)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010111 (1)(1)(0)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011000 (1)(1)(0)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011001 (1)(1)(0)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011010 (1)(1)(0)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011011 (1)(1)(0)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011100 (1)(1)(0)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011101 (1)(1)(0)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011110 (1)(1)(0)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011111 (1)(1)(0)(1)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100000 (1)(1)(1)(0)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100001 (1)(1)(1)(0)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100010 (1)(1)(1)(0)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100011 (1)(1)(1)(0)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100100 (1)(1)(1)(0)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100101 (1)(1)(1)(0)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100110 (1)(1)(1)(0)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100111 (1)(1)(1)(0)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101000 (1)(1)(1)(0)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101001 (1)(1)(1)(0)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101010 (1)(1)(1)(0)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101011 (1)(1)(1)(0)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101100 (1)(1)(1)(0)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101101 (1)(1)(1)(0)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101110 (1)(1)(1)(0)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101111 (1)(1)(1)(0)(1)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110000 (1)(1)(1)(1)(0)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110001 (1)(1)(1)(1)(0)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110010 (1)(1)(1)(1)(0)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110011 (1)(1)(1)(1)(0)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110100 (1)(1)(1)(1)(0)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110101 (1)(1)(1)(1)(0)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110110 (1)(1)(1)(1)(0)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110111 (1)(1)(1)(1)(0)(1)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111000 (1)(1)(1)(1)(1)(0)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111001 (1)(1)(1)(1)(1)(0)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111010 (1)(1)(1)(1)(1)(0)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111011 (1)(1)(1)(1)(1)(0)(1)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111100 (1)(1)(1)(1)(1)(1)(0)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111101 (1)(1)(1)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111110 (1)(1)(1)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111111 (1)(1)(1)(1)(1)(1)(1)(1),  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										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 | ||||
|  | ||||
							
								
								
									
										36
									
								
								include/boost/utility/detail/in_place_factory_prefix.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								include/boost/utility/detail/in_place_factory_prefix.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| // Copyright (C) 2003, Fernando Luis Cacciola Carballal. | ||||
| // Copyright (C) 2007, Tobias Schwinger. | ||||
| // | ||||
| // 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_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP | ||||
| #define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP | ||||
|  | ||||
| #include <new> | ||||
| #include <cstddef> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/preprocessor/cat.hpp> | ||||
| #include <boost/preprocessor/punctuation/paren.hpp> | ||||
| #include <boost/preprocessor/iteration/iterate.hpp> | ||||
| #include <boost/preprocessor/repetition/repeat.hpp> | ||||
| #include <boost/preprocessor/repetition/enum.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_params.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_binary_params.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | ||||
|  | ||||
| #define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT(z,n,_) BOOST_PP_CAT(m_a,n) BOOST_PP_LPAREN() BOOST_PP_CAT(a,n) BOOST_PP_RPAREN() | ||||
| #define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL(z,n,_) BOOST_PP_CAT(A,n) const& BOOST_PP_CAT(m_a,n); | ||||
|  | ||||
| #define BOOST_MAX_INPLACE_FACTORY_ARITY 10 | ||||
|  | ||||
| #undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP | ||||
|  | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										23
									
								
								include/boost/utility/detail/in_place_factory_suffix.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								include/boost/utility/detail/in_place_factory_suffix.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| // Copyright (C) 2003, Fernando Luis Cacciola Carballal. | ||||
| // Copyright (C) 2007, Tobias Schwinger. | ||||
| // | ||||
| // 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_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP | ||||
| #define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP | ||||
|  | ||||
| #undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT | ||||
| #undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL | ||||
| #undef BOOST_MAX_INPLACE_FACTORY_ARITY | ||||
|  | ||||
| #undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP | ||||
|  | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										89
									
								
								include/boost/utility/detail/result_of_iterate.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								include/boost/utility/detail/result_of_iterate.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| // Boost result_of library | ||||
|  | ||||
| //  Copyright Douglas 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 | ||||
| #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)> | ||||
|     : boost::detail::result_of_impl<F, F(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type<F>::value)> {}; | ||||
| #endif | ||||
|  | ||||
| #undef BOOST_RESULT_OF_ARGS | ||||
|  | ||||
| #if BOOST_PP_ITERATION() >= 1  | ||||
|  | ||||
| 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_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> | ||||
| { | ||||
|   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_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| #if !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_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), | ||||
|                  FArgs, false> | ||||
| { | ||||
|   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_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) | ||||
|                      const, | ||||
|                  FArgs, false> | ||||
| { | ||||
|   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_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) | ||||
|                      volatile, | ||||
|                  FArgs, false> | ||||
| { | ||||
|   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_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) | ||||
|                      const volatile, | ||||
|                  FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| } | ||||
| #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 (c) 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 Jarvi (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 | ||||
							
								
								
									
										88
									
								
								include/boost/utility/in_place_factory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								include/boost/utility/in_place_factory.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| // Copyright (C) 2003, Fernando Luis Cacciola Carballal. | ||||
| // Copyright (C) 2007, Tobias Schwinger. | ||||
| // | ||||
| // 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_INPLACE_FACTORY_04APR2007_HPP | ||||
| #ifndef BOOST_PP_IS_ITERATING | ||||
|  | ||||
| #include <boost/utility/detail/in_place_factory_prefix.hpp> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| class in_place_factory_base {} ; | ||||
|  | ||||
| #define  BOOST_PP_ITERATION_LIMITS (0, BOOST_MAX_INPLACE_FACTORY_ARITY) | ||||
| #define  BOOST_PP_FILENAME_1 <boost/utility/in_place_factory.hpp> | ||||
| #include BOOST_PP_ITERATE() | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #include <boost/utility/detail/in_place_factory_suffix.hpp> | ||||
|  | ||||
| #define BOOST_UTILITY_INPLACE_FACTORY_04APR2007_HPP | ||||
| #else | ||||
| #define N BOOST_PP_ITERATION() | ||||
|  | ||||
| #if N | ||||
| template< BOOST_PP_ENUM_PARAMS(N, class A) > | ||||
| #endif | ||||
| class BOOST_PP_CAT(in_place_factory,N) | ||||
|   :  | ||||
|   public in_place_factory_base | ||||
| { | ||||
| public: | ||||
|  | ||||
|   explicit BOOST_PP_CAT(in_place_factory,N) | ||||
|       ( BOOST_PP_ENUM_BINARY_PARAMS(N,A,const& a) ) | ||||
| #if N > 0 | ||||
|     : BOOST_PP_ENUM(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _) | ||||
| #endif | ||||
|   {} | ||||
|  | ||||
|   template<class T> | ||||
|   void* apply(void* address | ||||
|       BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const | ||||
|   { | ||||
|     return new(address) T( BOOST_PP_ENUM_PARAMS(N, m_a) ); | ||||
|   } | ||||
|  | ||||
|   template<class T> | ||||
|   void* apply(void* address, std::size_t n | ||||
|       BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const | ||||
|   { | ||||
|     for(char* next = address = this->BOOST_NESTED_TEMPLATE apply<T>(address); | ||||
|         !! --n;) | ||||
|       this->BOOST_NESTED_TEMPLATE apply<T>(next = next+sizeof(T)); | ||||
|     return address;  | ||||
|   } | ||||
|  | ||||
|   BOOST_PP_REPEAT(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) | ||||
| }; | ||||
|  | ||||
| #if N > 0 | ||||
| template< BOOST_PP_ENUM_PARAMS(N, class A) > | ||||
| inline BOOST_PP_CAT(in_place_factory,N)< BOOST_PP_ENUM_PARAMS(N, A) > | ||||
| in_place( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) ) | ||||
| { | ||||
|   return BOOST_PP_CAT(in_place_factory,N)< BOOST_PP_ENUM_PARAMS(N, A) > | ||||
|       ( BOOST_PP_ENUM_PARAMS(N, a) ); | ||||
| } | ||||
| #else | ||||
| inline in_place_factory0 in_place() | ||||
| { | ||||
|   return in_place_factory0(); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #undef N | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										88
									
								
								include/boost/utility/result_of.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								include/boost/utility/result_of.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| // Boost result_of library | ||||
|  | ||||
| //  Copyright Douglas 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/has_xxx.hpp> | ||||
| #include <boost/mpl/if.hpp> | ||||
| #include <boost/mpl/bool.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 result_of_impl; | ||||
|  | ||||
| template<typename F> | ||||
| struct result_of_void_impl | ||||
| { | ||||
|   typedef void type; | ||||
| }; | ||||
|  | ||||
| template<typename R> | ||||
| struct result_of_void_impl<R (*)(void)> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| template<typename R> | ||||
| struct result_of_void_impl<R (&)(void)> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| template<typename F, typename FArgs> | ||||
| struct result_of_impl<F, FArgs, true> | ||||
| { | ||||
|   typedef typename F::result_type type; | ||||
| }; | ||||
|  | ||||
| template<typename FArgs> | ||||
| struct is_function_with_no_args : mpl::false_ {}; | ||||
|  | ||||
| template<typename F> | ||||
| struct is_function_with_no_args<F(void)> : mpl::true_ {}; | ||||
|  | ||||
| template<typename F, typename FArgs> | ||||
| struct result_of_nested_result : F::template result<FArgs> | ||||
| {}; | ||||
|  | ||||
| template<typename F, typename FArgs> | ||||
| struct result_of_impl<F, FArgs, false> | ||||
|   : mpl::if_<is_function_with_no_args<FArgs>, | ||||
| 	     result_of_void_impl<F>, | ||||
| 	     result_of_nested_result<F, FArgs> >::type | ||||
| {}; | ||||
|  | ||||
| } // 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 | ||||
| #  define BOOST_NO_RESULT_OF 1 | ||||
| #endif | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif // BOOST_RESULT_OF_HPP | ||||
							
								
								
									
										77
									
								
								include/boost/utility/typed_in_place_factory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								include/boost/utility/typed_in_place_factory.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| // Copyright (C) 2003, Fernando Luis Cacciola Carballal. | ||||
| // Copyright (C) 2007, Tobias Schwinger. | ||||
| // | ||||
| // 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_TYPED_INPLACE_FACTORY_04APR2007_HPP | ||||
| #ifndef BOOST_PP_IS_ITERATING | ||||
|  | ||||
| #include <boost/utility/detail/in_place_factory_prefix.hpp> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| class typed_in_place_factory_base {} ; | ||||
|  | ||||
| #define  BOOST_PP_ITERATION_LIMITS (0, BOOST_MAX_INPLACE_FACTORY_ARITY) | ||||
| #define  BOOST_PP_FILENAME_1 <boost/utility/typed_in_place_factory.hpp> | ||||
| #include BOOST_PP_ITERATE() | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #include <boost/utility/detail/in_place_factory_suffix.hpp> | ||||
|  | ||||
| #define BOOST_UTILITY_TYPED_INPLACE_FACTORY_04APR2007_HPP | ||||
| #else  | ||||
| #define N BOOST_PP_ITERATION() | ||||
|  | ||||
| template< class T BOOST_PP_ENUM_TRAILING_PARAMS(N,class A) > | ||||
| class BOOST_PP_CAT(typed_in_place_factory,N)  | ||||
|   :  | ||||
|   public typed_in_place_factory_base | ||||
| { | ||||
| public: | ||||
|  | ||||
|   typedef T value_type; | ||||
|  | ||||
|   explicit BOOST_PP_CAT(typed_in_place_factory,N)  | ||||
|       ( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) ) | ||||
| #if N > 0 | ||||
|     : BOOST_PP_ENUM(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _) | ||||
| #endif | ||||
|   {} | ||||
|  | ||||
|   void* apply (void* address) const | ||||
|   { | ||||
|     return new(address) T( BOOST_PP_ENUM_PARAMS(N, m_a) ); | ||||
|   } | ||||
|  | ||||
|   void* apply (void* address, std::size_t n) const | ||||
|   { | ||||
|     for(void* next = address = this->apply(address); !! --n;) | ||||
|       this->apply(next = static_cast<char *>(next) + sizeof(T)); | ||||
|     return address;  | ||||
|   } | ||||
|  | ||||
|   BOOST_PP_REPEAT(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) | ||||
| }; | ||||
|  | ||||
| template< class T BOOST_PP_ENUM_TRAILING_PARAMS(N, class A) > | ||||
| inline BOOST_PP_CAT(typed_in_place_factory,N)< | ||||
|     T BOOST_PP_ENUM_TRAILING_PARAMS(N, A) > | ||||
| in_place( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) ) | ||||
| { | ||||
|   return BOOST_PP_CAT(typed_in_place_factory,N)<  | ||||
|       T BOOST_PP_ENUM_TRAILING_PARAMS(N, A) >( BOOST_PP_ENUM_PARAMS(N, a) ); | ||||
| } | ||||
|  | ||||
| #undef N | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										130
									
								
								include/boost/utility/value_init.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								include/boost/utility/value_init.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,130 @@ | ||||
| // (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal. | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| // 21 Ago 2002 (Created) Fernando Cacciola | ||||
| // 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker | ||||
| // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola | ||||
| // | ||||
| #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP | ||||
| #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP | ||||
|  | ||||
| // Note: The implementation of boost::value_initialized had to deal with the | ||||
| // fact that various compilers haven't fully implemented value-initialization. | ||||
| // The constructor of boost::value_initialized<T> works around these compiler | ||||
| // issues, by clearing the bytes of T, before constructing the T object it | ||||
| // contains. More details on these issues are at libs/utility/value_init.htm | ||||
|  | ||||
| #include <boost/aligned_storage.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/static_assert.hpp> | ||||
| #include <boost/type_traits/cv_traits.hpp> | ||||
| #include <boost/type_traits/alignment_of.hpp> | ||||
| #include <cstring> | ||||
| #include <new> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| template<class T> | ||||
| class value_initialized | ||||
| { | ||||
|   private : | ||||
|     struct wrapper | ||||
|     { | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) | ||||
|       typename | ||||
| #endif  | ||||
|       remove_const<T>::type data; | ||||
|     }; | ||||
|  | ||||
|     mutable | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) | ||||
|       typename | ||||
| #endif  | ||||
|       aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x; | ||||
|  | ||||
|     wrapper * wrapper_address() const | ||||
|     { | ||||
|       return static_cast<wrapper *>( static_cast<void*>(&x)); | ||||
|     } | ||||
|  | ||||
|   public : | ||||
|  | ||||
|     value_initialized() | ||||
|     { | ||||
|       std::memset(&x, 0, sizeof(x)); | ||||
| #ifdef BOOST_MSVC | ||||
| #pragma warning(push) | ||||
| #if _MSC_VER >= 1310 | ||||
| // When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345: | ||||
| // "behavior change: an object of POD type constructed with an initializer of the form () | ||||
| // will be default-initialized".  It is safe to ignore this warning when using value_initialized. | ||||
| #pragma warning(disable: 4345) | ||||
| #endif | ||||
| #endif | ||||
|       new (wrapper_address()) wrapper(); | ||||
| #ifdef BOOST_MSVC | ||||
| #pragma warning(pop) | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     value_initialized(value_initialized const & arg) | ||||
|     { | ||||
|       new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address()))); | ||||
|     } | ||||
|  | ||||
|     value_initialized & operator=(value_initialized const & arg) | ||||
|     { | ||||
|       // Assignment is only allowed when T is non-const. | ||||
|       BOOST_STATIC_ASSERT( ! is_const<T>::value ); | ||||
|       *wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address())); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     ~value_initialized() | ||||
|     { | ||||
|       wrapper_address()->wrapper::~wrapper(); | ||||
|     } | ||||
|  | ||||
|     T& data() const | ||||
|     { | ||||
|       return wrapper_address()->data; | ||||
|     } | ||||
|  | ||||
|     operator T&() const { return this->data(); } | ||||
|  | ||||
| } ; | ||||
|  | ||||
|  | ||||
|  | ||||
| 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() ; | ||||
| } | ||||
|  | ||||
|  | ||||
| class initialized_value_t | ||||
| { | ||||
|   public : | ||||
|      | ||||
|     template <class T> operator T() const | ||||
|     { | ||||
|       return get( value_initialized<T>() ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| initialized_value_t const initialized_value = {} ; | ||||
|  | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										41
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| <html> | ||||
| 	<head> | ||||
| 		<meta http-equiv="Content-Language" content="en-us"> | ||||
| 		<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> | ||||
| 		<meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
| 		<title>Boost Utility Library</title> | ||||
| 	</head> | ||||
| 	<body bgcolor="#FFFFFF"> | ||||
| 		<h1><IMG SRC="../../boost.png" WIDTH="276" HEIGHT="86" align="center">Boost  | ||||
| 			Utility Library</h1> | ||||
| 		<p>The Boost Utility Library isn't really a single library at all. It is just a  | ||||
| 			collection for components too small to be called libraries in their own right.</p> | ||||
| 		<p>But that doesn't mean there isn't useful stuff here. Take a look:</p> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<a href="assert.html">assert</a><br> | ||||
| 				<a href="base_from_member.html">base_from_member</a><br> | ||||
| 				<a href="call_traits.htm">call_traits</a><br> | ||||
| 				<a href="checked_delete.html">checked_delete</a><br> | ||||
| 				<a href="compressed_pair.htm">compressed_pair</a><br> | ||||
| 				<a href="current_function.html">current_function</a><br> | ||||
| 				<a href="enable_if.html">enable_if</a><br> | ||||
|             <a href="iterator_adaptors.htm">iterator_adaptors</a><br> | ||||
|             <a href="generator_iterator.htm">generator iterator adaptors</a><br> | ||||
| 				<a href="operators.htm">operators</a><br> | ||||
| 				<a href="throw_exception.html">throw_exception</a><br> | ||||
| 				<a href="utility.htm">utility</a><br> | ||||
|                 <a href="value_init.htm">value_init</a></p> | ||||
| 		</blockquote> | ||||
| 		<hr> | ||||
| 		<p>© Copyright Beman Dawes, 2001</p> | ||||
|         <p>Distributed under the Boost Software License, Version 1.0. (See  | ||||
|         accompanying file <a href="../../LICENSE_1_0.txt"> | ||||
|         LICENSE_1_0.txt</a> or copy at | ||||
|         <a href="http://www.boost.org/LICENSE_1_0.txt"> | ||||
|         www.boost.org/LICENSE_1_0.txt</a>)</p> | ||||
| 		<p>Revised  | ||||
| 			<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p> | ||||
| 		</body> | ||||
| </html> | ||||
| @@ -1,443 +0,0 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN"> | ||||
|  | ||||
| <html> | ||||
| <head> | ||||
|     <meta name="generator" content="HTML Tidy, see www.w3.org"> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
|     <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> | ||||
|     <meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
|  | ||||
|     <title>Indirect Iterator Adaptor Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
| 	 | ||||
|     <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align= | ||||
|     "center" width="277" height="86">  | ||||
|  | ||||
|     <h1>Indirect Iterator Adaptor</h1> | ||||
|     Defined in header <a href= | ||||
|     "../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>  | ||||
|  | ||||
|     <p>The indirect iterator adaptor augments an iterator by applying an | ||||
|     <b>extra</b> dereference inside of <tt>operator*()</tt>. For example, this | ||||
|     iterator makes it possible to view a container of pointers or | ||||
|     smart-pointers (e.g. <tt>std::list<boost::shared_ptr<foo> | ||||
|     ></tt>) as if it were a container of the pointed-to type. The following | ||||
|     <b>pseudo-code</b> shows the basic idea of the indirect iterator: | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| // inside a hypothetical indirect_iterator class... | ||||
| typedef std::iterator_traits<BaseIterator>::value_type Pointer; | ||||
| typedef std::iterator_traits<Pointer>::reference reference; | ||||
|  | ||||
| reference indirect_iterator::operator*() const { | ||||
|   return **this->base_iterator; | ||||
| } | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h2>Synopsis</h2> | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| namespace boost { | ||||
|   template <class BaseIterator, | ||||
|             class Value, class Reference, class Category, class Pointer> | ||||
|   struct indirect_iterator_generator; | ||||
|    | ||||
|   template <class BaseIterator, | ||||
|             class Value, class Reference, class ConstReference,  | ||||
|             class Category, class Pointer, class ConstPointer> | ||||
|   struct indirect_iterator_pair_generator; | ||||
|  | ||||
|   template <class BaseIterator> | ||||
|   typename indirect_iterator_generator<BaseIterator>::type | ||||
|   make_indirect_iterator(BaseIterator base)   | ||||
| } | ||||
| </pre> | ||||
|     </blockquote> | ||||
|     <hr> | ||||
|  | ||||
|     <h2><a name="indirect_iterator_generator">The Indirect Iterator Type | ||||
|     Generator</a></h2> | ||||
|     The <tt>indirect_iterator_generator</tt> template is a <a href= | ||||
|     "../../more/generic_programming.html#type_generator">generator</a> of | ||||
|     indirect iterator types. The main template parameter for this class is the | ||||
|     <tt>BaseIterator</tt> type that is being wrapped. In most cases the type of | ||||
|     the elements being pointed to can be deduced using | ||||
|     <tt>std::iterator_traits</tt>, but in some situations the user may want to | ||||
|     override this type, so there are also template parameters that allow a user | ||||
|     to control the <tt>value_type</tt>, <tt>pointer</tt>, and | ||||
|     <tt>reference</tt> types of the resulting iterators.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class BaseIterator, | ||||
|           class Value, class Reference, class Pointer> | ||||
| class indirect_iterator_generator | ||||
| { | ||||
| public: | ||||
|   typedef <tt><a href= | ||||
| "./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting indirect iterator type  | ||||
| }; | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Example</h3> | ||||
|     This example uses the <tt>indirect_iterator_generator</tt> to create | ||||
|     indirect iterators which dereference the pointers stored in the | ||||
|     <tt>pointers_to_chars</tt> array to access the <tt>char</tt>s in the | ||||
|     <tt>characters</tt> array.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| #include <boost/config.hpp> | ||||
| #include <vector> | ||||
| #include <iostream> | ||||
| #include <iterator> | ||||
| #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]; | ||||
|    | ||||
|   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; | ||||
|    | ||||
|   // to be continued... | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Template Parameters</h3> | ||||
|  | ||||
|     <table border> | ||||
|       <tr> | ||||
|         <th>Parameter | ||||
|  | ||||
|         <th>Description | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>BaseIterator</tt>  | ||||
|  | ||||
|         <td>The iterator type being wrapped. The <tt>value_type</tt> | ||||
|         of the base iterator should itself be dereferenceable.   | ||||
|         The return type of the <tt>operator*</tt> for the | ||||
|         <tt>value_type</tt> should match the <tt>Reference</tt> type. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Value</tt>  | ||||
|  | ||||
|         <td>The <tt>value_type</tt> of the resulting iterator, unless const. If | ||||
|         Value is <tt>const X</tt>, a conforming compiler makes the | ||||
|         <tt>value_type</tt> <tt><i>non-</i>const X</tt><a href= | ||||
|         "iterator_adaptors.htm#1">[1]</a>. Note that if the default | ||||
|          is used for <tt>Value</tt>, then there must be a valid specialization | ||||
|          of <tt>iterator_traits</tt> for the value type of the base iterator. | ||||
|          <br> | ||||
|          <b>Default:</b> <tt>std::iterator_traits<<br> | ||||
|          <20> std::iterator_traits<BaseIterator>::value_type | ||||
|         >::value_type</tt><a href="#2">[2]</a>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Reference</tt>  | ||||
|  | ||||
|         <td>The <tt>reference</tt> type of the resulting iterator, and in | ||||
|         particular, the result type of <tt>operator*()</tt>.<br> | ||||
|          <b>Default:</b> <tt>Value&</tt>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Pointer</tt>  | ||||
|  | ||||
|         <td>The <tt>pointer</tt> type of the resulting iterator, and in | ||||
|         particular, the result type of <tt>operator->()</tt>.<br> | ||||
|          <b>Default:</b> <tt>Value*</tt>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Category</tt>  | ||||
|         <td>The <tt>iterator_category</tt> type for the resulting iterator.<br> | ||||
|          <b>Default:</b> | ||||
|         <tt>std::iterator_traits<BaseIterator>::iterator_category</tt>  | ||||
|  | ||||
|     </table> | ||||
|  | ||||
|     <h3>Concept Model</h3> | ||||
|     The indirect iterator will model whichever <a href= | ||||
|     "http://www.sgi.com/tech/stl/Iterators.html">standard iterator | ||||
|     concept category</a> is modeled by the base iterator. Thus, if the | ||||
|     base iterator is a model of <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
|     Access Iterator</a> then so is the resulting indirect iterator. If | ||||
|     the base iterator models a more restrictive concept, the resulting | ||||
|     indirect iterator will model the same concept <a href="#3">[3]</a>. | ||||
|  | ||||
|     <h3>Members</h3> | ||||
|     The indirect iterator type implements the member functions and operators | ||||
|     required of the <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access | ||||
|     Iterator</a> concept. In addition it has the following constructor:  | ||||
| <pre> | ||||
| explicit indirect_iterator_generator::type(const BaseIterator& it) | ||||
| </pre> | ||||
|     <br> | ||||
|      <br> | ||||
|       | ||||
|     <hr> | ||||
|  | ||||
|     <p> | ||||
|  | ||||
|     <h2><a name="indirect_iterator_pair_generator">The Indirect Iterator Pair | ||||
|     Generator</a></h2> | ||||
|     Sometimes a pair of <tt>const</tt>/non-<tt>const</tt> pair of iterators is | ||||
|     needed, such as when implementing a container. The | ||||
|     <tt>indirect_iterator_pair_generator</tt> class makes it more convenient to | ||||
|     create this pair of iterator types.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class BaseIterator, | ||||
|           class Value, class Pointer, class Reference, | ||||
|           class ConstPointer, class ConstReference> | ||||
| class indirect_iterator_pair_generator | ||||
| { | ||||
| public: | ||||
|   typedef <tt><a href= | ||||
| "./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> iterator;       // the mutable indirect iterator type  | ||||
|   typedef <tt><a href= | ||||
| "./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> const_iterator; // the immutable indirect iterator type  | ||||
| }; | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Example</h3> | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
|   // continuing from the last example... | ||||
|  | ||||
|   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; | ||||
|   // to be continued... | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <p>The output is: | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| b,c,d,e,f,g,h, | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Template Parameters</h3> | ||||
|  | ||||
|     <table border> | ||||
|       <tr> | ||||
|         <th>Parameter | ||||
|  | ||||
|         <th>Description | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>BaseIterator</tt>  | ||||
|  | ||||
|         <td>The iterator type being wrapped. The <tt>value_type</tt> of the | ||||
|         base iterator should itself be dereferenceable. | ||||
|         The return type of the <tt>operator*</tt> for the | ||||
|         <tt>value_type</tt> should match the <tt>Reference</tt> type. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Value</tt>  | ||||
|  | ||||
|         <td>The <tt>value_type</tt> of the resulting iterators. | ||||
|          If Value is <tt>const X</tt>, a conforming compiler makes the | ||||
|          <tt>value_type</tt> <tt><i>non-</i>const X</tt><a href= | ||||
|          "iterator_adaptors.htm#1">[1]</a>. Note that if the default | ||||
|          is used for <tt>Value</tt>, then there must be a valid | ||||
|          specialization of <tt>iterator_traits</tt> for the value type | ||||
|          of the base iterator.<br> | ||||
|  | ||||
|          <b>Default:</b> <tt>std::iterator_traits<<br> | ||||
|          <20> std::iterator_traits<BaseIterator>::value_type | ||||
|         >::value_type</tt><a href="#2">[2]</a>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Reference</tt>  | ||||
|  | ||||
|         <td>The <tt>reference</tt> type of the resulting <tt>iterator</tt>, and | ||||
|         in particular, the result type of its <tt>operator*()</tt>.<br> | ||||
|          <b>Default:</b> <tt>Value&</tt>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Pointer</tt>  | ||||
|  | ||||
|         <td>The <tt>pointer</tt> type of the resulting <tt>iterator</tt>, and | ||||
|         in particular, the result type of its <tt>operator->()</tt>.<br> | ||||
|          <b>Default:</b> <tt>Value*</tt>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>ConstReference</tt>  | ||||
|  | ||||
|         <td>The <tt>reference</tt> type of the resulting | ||||
|         <tt>const_iterator</tt>, and in particular, the result type of its | ||||
|         <tt>operator*()</tt>.<br> | ||||
|          <b>Default:</b> <tt>const Value&</tt>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>ConstPointer</tt>  | ||||
|  | ||||
|         <td>The <tt>pointer</tt> type of the resulting <tt>const_iterator</tt>, | ||||
|         and in particular, the result type of its <tt>operator->()</tt>.<br> | ||||
|          <b>Default:</b> <tt>const Value*</tt>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Category</tt>  | ||||
|         <td>The <tt>iterator_category</tt> type for the resulting iterator.<br> | ||||
|          <b>Default:</b> | ||||
|         <tt>std::iterator_traits<BaseIterator>::iterator_category</tt>  | ||||
|     </table> | ||||
|  | ||||
|     <h3>Concept Model</h3> | ||||
|  | ||||
|     The indirect iterators will model whichever <a href= | ||||
|     "http://www.sgi.com/tech/stl/Iterators.html">standard iterator | ||||
|     concept category</a> is modeled by the base iterator. Thus, if the | ||||
|     base iterator is a model of <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
|     Access Iterator</a> then so are the resulting indirect | ||||
|     iterators. If the base iterator models a more restrictive concept, | ||||
|     the resulting indirect iterators will model the same concept <a | ||||
|     href="#3">[3]</a>. | ||||
|  | ||||
|  | ||||
|     <h3>Members</h3> | ||||
|     The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types implement | ||||
|     the member functions and operators required of the <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access | ||||
|     Iterator</a> concept. In addition they support the following constructors:  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| explicit indirect_iterator_pair_generator::iterator(const BaseIterator& it) | ||||
| explicit indirect_iterator_pair_generator::const_iterator(const BaseIterator& it) | ||||
| </pre> | ||||
|     </blockquote> | ||||
|     <br> | ||||
|      <br> | ||||
|       | ||||
|     <hr> | ||||
|  | ||||
|     <p> | ||||
|  | ||||
|     <h2><a name="make_indirect_iterator">The Indirect Iterator Object | ||||
|     Generator</a></h2> | ||||
|     The <tt>make_indirect_iterator()</tt> function provides a more convenient | ||||
|     way to create indirect iterator objects. The function saves the user the | ||||
|     trouble of explicitly writing out the iterator types.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class BaseIterator> | ||||
| typename indirect_iterator_generator<BaseIterator>::type | ||||
| make_indirect_iterator(BaseIterator base)   | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Example</h3> | ||||
|     Here we again print the <tt>char</tt>s from the array <tt>characters</tt> | ||||
|     by accessing them through the array of pointers <tt>pointer_to_chars</tt>, | ||||
|     but this time we use the <tt>make_indirect_iterator()</tt> function which | ||||
|     saves us some typing.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
|   // continuing from the last example... | ||||
|  | ||||
|   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; | ||||
| } | ||||
| </pre> | ||||
|     </blockquote> | ||||
|     The output is:  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| a,b,c,d,e,f,g, | ||||
| </pre> | ||||
|     </blockquote> | ||||
|     <hr> | ||||
|  | ||||
|     <h3>Notes</h3> | ||||
|  | ||||
|     <p> | ||||
|  | ||||
|     <p><a name="2">[2]</a> If your compiler does not support partial | ||||
|     specialization and the base iterator or its <tt>value_type</tt> is a | ||||
|     builtin pointer type, you will not be able to use the default for | ||||
|     <tt>Value</tt> and will need to specify this type explicitly. | ||||
|  | ||||
|     <p><a name="3">[3]</a>There is a caveat to which concept the | ||||
|     indirect iterator can model.  If the return type of the | ||||
|     <tt>operator*</tt> for the base iterator's value type is not a | ||||
|     true reference, then strickly speaking, the indirect iterator can | ||||
|     not be a model of <a href= | ||||
|     "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward | ||||
|     Iterator</a> or any of the concepts that refine it. In this case | ||||
|     the <tt>Category</tt> for the indirect iterator should be | ||||
|     specified as <tt>std::input_iterator_tag</tt>. However, even in | ||||
|     this case, if the base iterator is a random access iterator, the | ||||
|     resulting indirect iterator will still satisfy most of the | ||||
|     requirements for <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
|     Access Iterator</a>. | ||||
|      | ||||
|     <hr> | ||||
|  | ||||
|     <p>Revised  | ||||
|     <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" --> | ||||
|  | ||||
|  | ||||
|     <p>© Copyright Jeremy Siek and David Abrahams 2001. 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.  | ||||
|     <!--  LocalWords:  html charset alt gif hpp BaseIterator const namespace struct | ||||
|              --> | ||||
|       | ||||
|     <!--  LocalWords:  ConstPointer ConstReference typename iostream int abcdefg | ||||
|              --> | ||||
|      <!--  LocalWords:  sizeof  PairGen pre Jeremy Siek David Abrahams | ||||
|              --> | ||||
|  | ||||
|  | ||||
| </body> | ||||
| </html> | ||||
| @@ -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; | ||||
| } | ||||
| @@ -1,151 +0,0 @@ | ||||
| //  (C) Copyright Jeremy Siek 1999. 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 | ||||
| //  08 Mar 2001   Jeremy Siek | ||||
| //       Moved test of indirect iterator into its own file. It to | ||||
| //       to be in iterator_adaptor_test.cpp. | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <iostream> | ||||
| #include <algorithm> | ||||
|  | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
| #include <boost/pending/iterator_tests.hpp> | ||||
| #include <boost/concept_archetype.hpp> | ||||
| #include <stdlib.h> | ||||
| #include <deque> | ||||
| #include <set> | ||||
|  | ||||
| struct my_iterator_tag : public std::random_access_iterator_tag { }; | ||||
|  | ||||
| using boost::dummyT; | ||||
|  | ||||
| typedef std::deque<int> storage; | ||||
| typedef std::deque<int*> pointer_deque; | ||||
| typedef std::set<storage::iterator> iterator_set; | ||||
|  | ||||
| void more_indirect_iterator_tests() | ||||
| { | ||||
| // For some reason all heck breaks loose in the compiler under these conditions. | ||||
| #if !defined(BOOST_MSVC) || !defined(__STL_DEBUG) | ||||
|     storage store(1000); | ||||
|     std::generate(store.begin(), store.end(), rand); | ||||
|      | ||||
|     pointer_deque ptr_deque; | ||||
|     iterator_set iter_set; | ||||
|  | ||||
|     for (storage::iterator p = store.begin(); p != store.end(); ++p) | ||||
|     { | ||||
|         ptr_deque.push_back(&*p); | ||||
|         iter_set.insert(p); | ||||
|     } | ||||
|  | ||||
|     typedef boost::indirect_iterator_pair_generator< | ||||
|         pointer_deque::iterator | ||||
| #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|         , int | ||||
| #endif | ||||
|     > IndirectDeque; | ||||
|  | ||||
|     IndirectDeque::iterator db(ptr_deque.begin()); | ||||
|     IndirectDeque::iterator de(ptr_deque.end()); | ||||
|     assert(static_cast<std::size_t>(de - db) == store.size()); | ||||
|     assert(db + store.size() == de); | ||||
|     IndirectDeque::const_iterator dci(db); | ||||
|     assert(db == dci); | ||||
|     assert(dci == db); | ||||
|     assert(dci != de); | ||||
|     assert(dci < de); | ||||
|     assert(dci <= de); | ||||
|     assert(de >= dci); | ||||
|     assert(de > dci); | ||||
|     dci = de; | ||||
|     assert(dci == de); | ||||
|  | ||||
|     boost::random_access_iterator_test(db + 1, store.size() - 1, boost::next(store.begin())); | ||||
|      | ||||
|     *db = 999; | ||||
|     assert(store.front() == 999); | ||||
|  | ||||
|     // Borland C++ is getting very confused about the typedef's here | ||||
|  | ||||
|     typedef boost::indirect_iterator_generator< | ||||
|         iterator_set::iterator | ||||
| #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|         , int | ||||
| #endif | ||||
|         >::type indirect_set_iterator; | ||||
|  | ||||
|     typedef boost::indirect_iterator_generator< | ||||
|         iterator_set::iterator, | ||||
|         const int | ||||
|         >::type const_indirect_set_iterator; | ||||
|  | ||||
|     indirect_set_iterator sb(iter_set.begin()); | ||||
|     indirect_set_iterator se(iter_set.end()); | ||||
|     const_indirect_set_iterator sci(iter_set.begin()); | ||||
|     assert(sci == sb); | ||||
|     assert(sci != se); | ||||
|     sci = se; | ||||
|     assert(sci == se); | ||||
|      | ||||
|     *boost::prior(se) = 888; | ||||
|     assert(store.back() == 888); | ||||
|     assert(std::equal(sb, se, store.begin())); | ||||
|  | ||||
|     boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]); | ||||
|     assert(std::equal(db, de, store.begin())); | ||||
|  | ||||
| #endif     | ||||
| } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),  | ||||
|                      dummyT(3), dummyT(4), dummyT(5) }; | ||||
|   const int N = sizeof(array)/sizeof(dummyT); | ||||
|  | ||||
|   // Test indirect_iterator_generator | ||||
|   { | ||||
|     dummyT* ptr[N]; | ||||
|     for (int k = 0; k < N; ++k) | ||||
|       ptr[k] = array + k; | ||||
|  | ||||
|     typedef boost::indirect_iterator_generator<dummyT** | ||||
| #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|         , dummyT | ||||
| #endif | ||||
|       >::type indirect_iterator; | ||||
|  | ||||
|     typedef boost::indirect_iterator_generator<dummyT**, const dummyT>::type const_indirect_iterator; | ||||
|  | ||||
|     indirect_iterator i(ptr); | ||||
|     boost::random_access_iterator_test(i, N, array); | ||||
|  | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|     boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array); | ||||
| #endif | ||||
|      | ||||
|     // check operator-> | ||||
|     assert((*i).m_x == i->foo()); | ||||
|  | ||||
|     const_indirect_iterator j(ptr); | ||||
|     boost::random_access_iterator_test(j, N, array); | ||||
|  | ||||
|     dummyT*const* const_ptr = ptr; | ||||
|      | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|     boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array); | ||||
| #endif | ||||
|     boost::const_nonconst_iterator_test(i, ++j); | ||||
|  | ||||
|     more_indirect_iterator_tests(); | ||||
|   } | ||||
|   std::cout << "test successful " << std::endl; | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,27 +0,0 @@ | ||||
| //  Test boost/pending/iterator_adaptors.hpp | ||||
|  | ||||
| //  (C) Copyright Jeremy Siek 1999. 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 | ||||
| // 21 Jan 01 Initial version (Jeremy Siek) | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <list> | ||||
| #include <boost/pending/iterator_adaptors.hpp> | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   typedef boost::iterator_adaptor<std::list<int>::iterator, | ||||
|     boost::default_iterator_policies, | ||||
|     int,int&,int*,std::bidirectional_iterator_tag> adaptor_type; | ||||
|    | ||||
|   adaptor_type i; | ||||
|   i += 4; | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,28 +0,0 @@ | ||||
| //  Test boost/pending/iterator_adaptors.hpp | ||||
|  | ||||
| //  (C) Copyright Jeremy Siek 1999. 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 | ||||
| // 21 Jan 01 Initial version (Jeremy Siek) | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <iostream> | ||||
| #include <iterator> | ||||
| #include <boost/pending/iterator_adaptors.hpp> | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   typedef boost::iterator_adaptor<std::istream_iterator<int>, | ||||
|     boost::default_iterator_policies, | ||||
|     int,int&,int*,std::input_iterator_tag> adaptor_type; | ||||
|    | ||||
|   adaptor_type iter; | ||||
|   --iter; | ||||
|   return 0; | ||||
| } | ||||
| @@ -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. | ||||
|  | ||||
| // 8 Mar 2001   Jeremy Siek | ||||
| //     Initial checkin. | ||||
|  | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
| #include <boost/pending/iterator_tests.hpp> | ||||
| #include <boost/static_assert.hpp> | ||||
|  | ||||
| class bar { }; | ||||
| void foo(bar) { } | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   using boost::dummyT; | ||||
|   dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),  | ||||
| 		     dummyT(3), dummyT(4), dummyT(5) }; | ||||
|   typedef boost::iterator_adaptor<dummyT*,  | ||||
|     boost::default_iterator_policies, dummyT> my_iter; | ||||
|   my_iter mi(array); | ||||
|  | ||||
|   { | ||||
|     typedef boost::iterator_adaptor<my_iter, boost::default_iterator_policies, | ||||
|       boost::iterator_traits_generator | ||||
|       ::reference<dummyT> | ||||
|       ::iterator_category<std::input_iterator_tag> > iter_type; | ||||
|  | ||||
|     BOOST_STATIC_ASSERT((boost::is_same<iter_type::iterator_category*, | ||||
|        std::input_iterator_tag*>::value)); | ||||
|  | ||||
|     BOOST_STATIC_ASSERT(( ! boost::is_convertible<iter_type::iterator_category*, | ||||
|        std::forward_iterator_tag*>::value)); | ||||
|  | ||||
|     iter_type i(mi); | ||||
|     boost::input_iterator_test(i, dummyT(0), dummyT(1)); | ||||
|   } | ||||
|   { | ||||
|     typedef boost::iterator_adaptor<dummyT*, | ||||
|       boost::default_iterator_policies, | ||||
|       boost::iterator_traits_generator | ||||
|         ::value_type<dummyT> | ||||
|         ::reference<const dummyT&> | ||||
|         ::pointer<const dummyT*>  | ||||
|         ::iterator_category<std::forward_iterator_tag> | ||||
|         ::difference_type<std::ptrdiff_t> > adaptor_type; | ||||
|  | ||||
|     adaptor_type i(array); | ||||
|  | ||||
|     boost::input_iterator_test(i, dummyT(0), dummyT(1)); | ||||
|     int zero = 0; | ||||
|     if (zero) // don't do this, just make sure it compiles | ||||
|       assert((*i).m_x == i->foo());       | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,47 +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 <functional> | ||||
| #include <algorithm> | ||||
| #include <iostream> | ||||
| #include <boost/pending/iterator_adaptors.hpp> | ||||
| #include <boost/pending/integer_range.hpp> | ||||
|  | ||||
| int | ||||
| main(int, char*[]) | ||||
| { | ||||
|   // This is a simple example of using the transform_iterators class to | ||||
|   // generate iterators that multiply the value returned by dereferencing | ||||
|   // the iterator. In this case we are multiplying by 2. | ||||
|   // Would be cooler to use lambda library in this example. | ||||
|  | ||||
|   int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; | ||||
|  | ||||
|   typedef std::binder1st< std::multiplies<int> > Function; | ||||
|   typedef boost::transform_iterator<Function, int*,  | ||||
|     boost::iterator<std::random_access_iterator_tag, int> | ||||
|   >::type doubling_iterator; | ||||
|  | ||||
|   doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)), | ||||
|     i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies<int>(), 2)); | ||||
|  | ||||
|   std::cout << "multiplying the array by 2:" << std::endl; | ||||
|   while (i != i_end) | ||||
|     std::cout << *i++ << " "; | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // Here is an example of counting from 0 to 5 using the integer_range class. | ||||
|  | ||||
|   boost::integer_range<int> r(0,5); | ||||
|  | ||||
|   std::cout << "counting to from 0 to 4:" << std::endl; | ||||
|   std::copy(r.begin(), r.end(), std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1,335 +0,0 @@ | ||||
| //  Test boost/iterator_adaptors.hpp | ||||
|  | ||||
| //  (C) Copyright Jeremy Siek 1999. 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 | ||||
| //  08 Mar 01 Moved indirect and transform tests to separate files. | ||||
| //            (Jeremy Siek) | ||||
| //  19 Feb 01 Take adavantage of improved iterator_traits to do more tests | ||||
| //            on MSVC. Hack around an MSVC-with-STLport internal compiler | ||||
| //            error. (David Abrahams) | ||||
| //  11 Feb 01 Added test of operator-> for forward and input iterators. | ||||
| //            (Jeremy Siek) | ||||
| //  11 Feb 01 Borland fixes (David Abrahams) | ||||
| //  10 Feb 01 Use new adaptors interface. (David Abrahams) | ||||
| //  10 Feb 01 Use new filter_ interface. (David Abrahams) | ||||
| //  09 Feb 01 Use new reverse_ and indirect_ interfaces. Replace | ||||
| //            BOOST_NO_STD_ITERATOR_TRAITS with | ||||
| //            BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION to prove we've | ||||
| //            normalized to core compiler capabilities (David Abrahams) | ||||
| //  08 Feb 01 Use Jeremy's new make_reverse_iterator form; add more | ||||
| //            comprehensive testing. Force-decay array function arguments to | ||||
| //            pointers. | ||||
| //  07 Feb 01 Added tests for the make_xxx_iterator() helper functions. | ||||
| //            (Jeremy Siek) | ||||
| //  07 Feb 01 Replaced use of xxx_pair_generator with xxx_generator where | ||||
| //            possible (which was all but the projection iterator). | ||||
| //            (Jeremy Siek) | ||||
| //  06 Feb 01 Removed now-defaulted template arguments where possible | ||||
| //            Updated names to correspond to new generator naming convention. | ||||
| //            Added a trivial test for make_transform_iterator(). | ||||
| //            Gave traits for const iterators a mutable value_type, per std. | ||||
| //            Resurrected my original tests for indirect iterators. | ||||
| //            (David Abrahams) | ||||
| //  04 Feb 01 Fix for compilers without standard iterator_traits | ||||
| //            (David Abrahams) | ||||
| //  13 Jun 00 Added const version of the iterator tests (Jeremy Siek) | ||||
| //  12 Dec 99 Initial version with iterator operators (Jeremy Siek) | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <iostream> | ||||
|  | ||||
| #include <algorithm> | ||||
| #include <functional> | ||||
|  | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
| #include <boost/pending/iterator_tests.hpp> | ||||
| #include <boost/pending/integer_range.hpp> | ||||
| #include <boost/concept_archetype.hpp> | ||||
| #include <stdlib.h> | ||||
| #include <vector> | ||||
| #include <deque> | ||||
| #include <set> | ||||
|  | ||||
| struct my_iterator_tag : public std::random_access_iterator_tag { }; | ||||
|  | ||||
| using boost::dummyT; | ||||
|  | ||||
|  | ||||
| struct mult_functor { | ||||
|   typedef int result_type; | ||||
|   typedef int argument_type; | ||||
|   // Functors used with transform_iterator must be | ||||
|   // DefaultConstructible, as the transform_iterator must be | ||||
|   // DefaultConstructible to satisfy the requirements for | ||||
|   // TrivialIterator. | ||||
|   mult_functor() { } | ||||
|   mult_functor(int aa) : a(aa) { } | ||||
|   int operator()(int b) const { return a * b; } | ||||
|   int a; | ||||
| }; | ||||
|  | ||||
| template <class Pair> | ||||
| struct select1st_  | ||||
|   : public std::unary_function<Pair, typename Pair::first_type> | ||||
| { | ||||
|   const typename Pair::first_type& operator()(const Pair& x) const { | ||||
|     return x.first; | ||||
|   } | ||||
|   typename Pair::first_type& operator()(Pair& x) const { | ||||
|     return x.first; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| struct one_or_four { | ||||
|   bool operator()(dummyT x) const { | ||||
|     return x.foo() == 1 || x.foo() == 4; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| typedef std::deque<int> storage; | ||||
| typedef std::deque<int*> pointer_deque; | ||||
| typedef std::set<storage::iterator> iterator_set; | ||||
|  | ||||
| int | ||||
| main() | ||||
| { | ||||
|   dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),  | ||||
|                      dummyT(3), dummyT(4), dummyT(5) }; | ||||
|   const int N = sizeof(array)/sizeof(dummyT); | ||||
|  | ||||
|   // sanity check, if this doesn't pass the test is buggy | ||||
|   boost::random_access_iterator_test(array,N,array); | ||||
|  | ||||
|   // Check that the policy concept checks and the default policy | ||||
|   // implementation match up. | ||||
|   boost::function_requires<  | ||||
|      boost::RandomAccessIteratorPoliciesConcept< | ||||
|        boost::default_iterator_policies, int*, | ||||
|        boost::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t, | ||||
|                       int*, int&> | ||||
|       > >(); | ||||
|  | ||||
|   // Test the iterator_adaptor | ||||
|   { | ||||
|     boost::iterator_adaptor<dummyT*, boost::default_iterator_policies, dummyT> i(array); | ||||
|     boost::random_access_iterator_test(i, N, array); | ||||
|      | ||||
|     boost::iterator_adaptor<const dummyT*, boost::default_iterator_policies, const dummyT> j(array); | ||||
|     boost::random_access_iterator_test(j, N, array); | ||||
|     boost::const_nonconst_iterator_test(i, ++j); | ||||
|   } | ||||
|  | ||||
|   // Test projection_iterator_pair_generator | ||||
|   {     | ||||
|     typedef std::pair<dummyT,dummyT> Pair; | ||||
|     Pair pair_array[N]; | ||||
|     for (int k = 0; k < N; ++k) | ||||
|       pair_array[k].first = array[k]; | ||||
|  | ||||
|     typedef boost::projection_iterator_pair_generator<select1st_<Pair>, | ||||
|       Pair*, const Pair* | ||||
|       > Projection; | ||||
|      | ||||
|     Projection::iterator i(pair_array); | ||||
|     boost::random_access_iterator_test(i, N, array); | ||||
|  | ||||
|     boost::random_access_iterator_test(boost::make_projection_iterator(pair_array, select1st_<Pair>()), N, array);     | ||||
|     boost::random_access_iterator_test(boost::make_projection_iterator< select1st_<Pair> >(pair_array), N, array);     | ||||
|  | ||||
|     Projection::const_iterator j(pair_array); | ||||
|     boost::random_access_iterator_test(j, N, array); | ||||
|  | ||||
|     boost::random_access_iterator_test(boost::make_const_projection_iterator(pair_array, select1st_<Pair>()), N, array); | ||||
|     boost::random_access_iterator_test(boost::make_const_projection_iterator<select1st_<Pair> >(pair_array), N, array); | ||||
|  | ||||
|     boost::const_nonconst_iterator_test(i, ++j); | ||||
|   } | ||||
|  | ||||
|   // Test reverse_iterator_generator | ||||
|   { | ||||
|     dummyT reversed[N]; | ||||
|     std::copy(array, array + N, reversed); | ||||
|     std::reverse(reversed, reversed + N); | ||||
|      | ||||
|     typedef boost::reverse_iterator_generator<dummyT* | ||||
| #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|         , dummyT | ||||
| #endif | ||||
|       >::type reverse_iterator; | ||||
|      | ||||
|     reverse_iterator i(reversed + N); | ||||
|     boost::random_access_iterator_test(i, N, array); | ||||
|  | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|     boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array); | ||||
| #endif | ||||
|  | ||||
|     typedef boost::reverse_iterator_generator<const dummyT* | ||||
| #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|         , const dummyT | ||||
| #endif | ||||
|       >::type const_reverse_iterator; | ||||
|      | ||||
|     const_reverse_iterator j(reversed + N); | ||||
|     boost::random_access_iterator_test(j, N, array); | ||||
|  | ||||
|     const dummyT* const_reversed = reversed; | ||||
|      | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|     boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array); | ||||
| #endif | ||||
|      | ||||
|     boost::const_nonconst_iterator_test(i, ++j);     | ||||
|   } | ||||
|  | ||||
|   // Test reverse_iterator_generator again, with traits fully deducible on all platforms | ||||
|   { | ||||
|     std::deque<dummyT> reversed_container; | ||||
|     std::reverse_copy(array, array + N, std::back_inserter(reversed_container)); | ||||
|     const std::deque<dummyT>::iterator reversed = reversed_container.begin(); | ||||
|  | ||||
|  | ||||
|     typedef boost::reverse_iterator_generator< | ||||
|         std::deque<dummyT>::iterator>::type reverse_iterator; | ||||
|     typedef boost::reverse_iterator_generator< | ||||
|         std::deque<dummyT>::const_iterator, const dummyT>::type const_reverse_iterator; | ||||
|  | ||||
|     // MSVC/STLport gives an INTERNAL COMPILER ERROR when any computation | ||||
|     // (e.g. "reversed + N") is used in the constructor below. | ||||
|     const std::deque<dummyT>::iterator finish = reversed_container.end(); | ||||
|     reverse_iterator i(finish); | ||||
|      | ||||
|     boost::random_access_iterator_test(i, N, array); | ||||
|     boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array); | ||||
|  | ||||
|     const_reverse_iterator j = reverse_iterator(finish); | ||||
|     boost::random_access_iterator_test(j, N, array); | ||||
|  | ||||
|     const std::deque<dummyT>::const_iterator const_reversed = reversed; | ||||
|     boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array); | ||||
|      | ||||
|     // Many compilers' builtin deque iterators don't interoperate well, though | ||||
|     // STLport fixes that problem. | ||||
| #if defined(__SGI_STL_PORT) || !defined(__GNUC__) && !defined(__BORLANDC__) && !defined(BOOST_MSVC) | ||||
|     boost::const_nonconst_iterator_test(i, ++j); | ||||
| #endif | ||||
|   } | ||||
|    | ||||
|   // Test integer_range's iterators | ||||
|   { | ||||
|     int int_array[] = { 0, 1, 2, 3, 4, 5 }; | ||||
|     boost::integer_range<int> r(0, 5); | ||||
|     boost::random_access_iterator_test(r.begin(), r.size(), int_array); | ||||
|   } | ||||
|  | ||||
|   // Test filter iterator | ||||
|   { | ||||
|     // Using typedefs for filter_gen::type confused Borland terribly. | ||||
|     typedef boost::detail::non_bidirectional_category<dummyT*>::type category; | ||||
|      | ||||
|     typedef boost::filter_iterator_generator<one_or_four, dummyT* | ||||
| #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|         , dummyT | ||||
| #endif | ||||
|         >::type filter_iter; | ||||
|  | ||||
| #if defined(__BORLANDC__) | ||||
|     // Borland is choking on accessing the policies_type explicitly | ||||
|     // from the filter_iter.  | ||||
|     boost::forward_iterator_test(make_filter_iterator(array, array+N,  | ||||
| 						      one_or_four()), | ||||
| 				 dummyT(1), dummyT(4)); | ||||
| #else | ||||
|     filter_iter i(array, filter_iter::policies_type(one_or_four(), array + N)); | ||||
|     boost::forward_iterator_test(i, dummyT(1), dummyT(4)); | ||||
| #endif | ||||
|  | ||||
| #if !defined(__BORLANDC__) | ||||
|     //  | ||||
|     enum { is_forward = boost::is_same< | ||||
|            filter_iter::iterator_category, | ||||
|            std::forward_iterator_tag>::value }; | ||||
|     BOOST_STATIC_ASSERT(is_forward); | ||||
| #endif | ||||
|  | ||||
|     // On compilers not supporting partial specialization, we can do more type | ||||
|     // deduction with deque iterators than with pointers... unless the library | ||||
|     // is broken ;-( | ||||
| #if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT) | ||||
|     std::deque<dummyT> array2; | ||||
|     std::copy(array+0, array+N, std::back_inserter(array2)); | ||||
|     boost::forward_iterator_test( | ||||
|         boost::make_filter_iterator(array2.begin(), array2.end(), one_or_four()), | ||||
|         dummyT(1), dummyT(4)); | ||||
|  | ||||
|     boost::forward_iterator_test( | ||||
|         boost::make_filter_iterator<one_or_four>(array2.begin(), array2.end()), | ||||
|         dummyT(1), dummyT(4)); | ||||
| #endif | ||||
|  | ||||
| #if !defined(BOOST_MSVC) // This just freaks MSVC out completely | ||||
|     boost::forward_iterator_test( | ||||
|         boost::make_filter_iterator<one_or_four>( | ||||
|             boost::make_reverse_iterator(array2.end()), | ||||
|             boost::make_reverse_iterator(array2.begin()) | ||||
|             ), | ||||
|         dummyT(4), dummyT(1)); | ||||
| #endif | ||||
|      | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|     boost::forward_iterator_test( | ||||
|         boost::make_filter_iterator(array+0, array+N, one_or_four()), | ||||
|         dummyT(1), dummyT(4)); | ||||
|  | ||||
|     boost::forward_iterator_test( | ||||
|         boost::make_filter_iterator<one_or_four>(array, array + N), | ||||
|         dummyT(1), dummyT(4)); | ||||
|  | ||||
| #endif | ||||
|   } | ||||
|  | ||||
|   // check operator-> with a forward iterator | ||||
|   { | ||||
|     boost::forward_iterator_archetype<dummyT> forward_iter; | ||||
| #if defined(__BORLANDC__) | ||||
|     typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>, | ||||
|       boost::default_iterator_policies, | ||||
|       dummyT, const dummyT&, const dummyT*,  | ||||
|       std::forward_iterator_tag, std::ptrdiff_t> adaptor_type; | ||||
| #else | ||||
|     typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>, | ||||
|       boost::default_iterator_policies, | ||||
|       boost::iterator_traits_generator | ||||
|         ::value_type<dummyT> | ||||
|         ::reference<const dummyT&> | ||||
|         ::pointer<const dummyT*>  | ||||
|         ::iterator_category<std::forward_iterator_tag> | ||||
|         ::difference_type<std::ptrdiff_t> > adaptor_type; | ||||
| #endif | ||||
|     adaptor_type i(forward_iter); | ||||
|     int zero = 0; | ||||
|     if (zero) // don't do this, just make sure it compiles | ||||
|       assert((*i).m_x == i->foo());       | ||||
|   } | ||||
|   // check operator-> with an input iterator | ||||
|   { | ||||
|     boost::input_iterator_archetype<dummyT> input_iter; | ||||
|     typedef boost::iterator_adaptor<boost::input_iterator_archetype<dummyT>, | ||||
|       boost::default_iterator_policies, | ||||
|       dummyT, const dummyT&, const dummyT*,  | ||||
|       std::input_iterator_tag, std::ptrdiff_t> adaptor_type; | ||||
|     adaptor_type i(input_iter); | ||||
|     int zero = 0; | ||||
|     if (zero) // don't do this, just make sure it compiles | ||||
|       assert((*i).m_x == i->foo());       | ||||
|   } | ||||
|   std::cout << "test successful " << std::endl; | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,863 +1,11 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <!-- Copyright David Abrahams 2004. Distributed under the Boost --> | ||||
| <!-- Software License, Version 1.0. (See accompanying --> | ||||
| <!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> | ||||
| <html> | ||||
| <head> | ||||
|     <meta name="generator" content="HTML Tidy, see www.w3.org"> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
|     <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> | ||||
|     <meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
|  | ||||
|     <title>Boost Iterator Adaptor Library</title> | ||||
| <meta http-equiv="refresh" content="0; URL=../iterator/doc/index.html"> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|  | ||||
|     <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align= | ||||
|     "center" width="277" height="86">  | ||||
|  | ||||
|     <h1>Boost Iterator Adaptor Library</h1> | ||||
|  | ||||
|     <h2>Introduction</h2> | ||||
|  | ||||
|     <p>The Iterator Adaptor library allows you transform an arbitrary ``base'' | ||||
|     type into a standard-conforming iterator with the behaviors you choose. | ||||
|     Doing so is especially easy if the ``base'' type is itself an iterator. The | ||||
|     library also supplies several example <a href= | ||||
|     "../../more/generic_programming.html#adaptors">adaptors</a> which apply | ||||
|     specific useful behaviors to arbitrary base iterators. | ||||
|  | ||||
|     <h2>Table of Contents</h2> | ||||
|  | ||||
|     <ul> | ||||
|       <li> | ||||
|         Header <tt><a href= | ||||
|         "../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a></tt> | ||||
|          | ||||
|  | ||||
|         <ul> | ||||
|           <li> | ||||
|             Generalized Iterator Adaptor  | ||||
|  | ||||
|             <ul> | ||||
|               <li>Class template <tt><a href= | ||||
|               "#iterator_adaptor">iterator_adaptor</a></tt> | ||||
|  | ||||
|               <li><a href="#template_parameters">Template Parameters</a> | ||||
|  | ||||
|               <li><a href="#named_template_parameters">Named Template Parameters</a> | ||||
|  | ||||
|               <li><a href="#policies">The Policies Class</a> | ||||
|  | ||||
|               <li><a href="#additional_members">Additional Class Members</a> | ||||
|  | ||||
|               <li><a href="#example">Example</a> | ||||
|  | ||||
|               <li>(<tt>const</tt>/non-<tt>const</tt>) <a href= | ||||
|               "#iterator_interactions">Iterator Interactions</a> | ||||
|  | ||||
|               <li><a href="#challenge">Challenge</a> | ||||
|  | ||||
|               <li><a href="#concept_model">Concept Model</a> | ||||
|  | ||||
|               <li><a href="#declaration_synopsis">Declaration Synopsis</a> | ||||
|  | ||||
|               <li><a href="#notes">Notes</a> | ||||
|             </ul> | ||||
|  | ||||
|           <li> | ||||
|             <a name="specialized_adaptors">Specialized Iterator Adaptors</a>  | ||||
|  | ||||
|             <ul> | ||||
|               <li><a href="indirect_iterator.htm">Indirect Iterator Adaptor</a> | ||||
|  | ||||
|               <li><a href="reverse_iterator.htm">Reverse Iterator Adaptor</a> | ||||
|  | ||||
|               <li><a href="transform_iterator.htm">Transform Iterator | ||||
|               Adaptor</a> | ||||
|  | ||||
|               <li><a href="projection_iterator.htm">Projection Iterator | ||||
|               Adaptor</a> | ||||
|  | ||||
|               <li><a href="filter_iterator.htm">Filter Iterator Adaptor</a> | ||||
|             </ul> | ||||
|         </ul> | ||||
|  | ||||
|       <li>Header <tt><a href= | ||||
|       "../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a></tt><br> | ||||
|  | ||||
|        <a href="counting_iterator.htm">Counting Iterator Adaptor</a> | ||||
|  | ||||
|       <li>Header <tt><a href= | ||||
|       "../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a></tt><br> | ||||
|  | ||||
|        <a href="function_output_iterator.htm">Function Output Iterator Adaptor</a> | ||||
|     </ul> | ||||
|  | ||||
|     <p><b><a href="http://www.boost.org/people/dave_abrahams.htm">Dave | ||||
|     Abrahams</a></b> started the library, applying <a href= | ||||
|     "../../more/generic_programming.html#policy">policy class</a> technique and | ||||
|     handling const/non-const iterator interactions. He also contributed the | ||||
|     <tt><a href="indirect_iterator.htm">indirect_</a></tt> and <tt><a href= | ||||
|     "reverse_iterator.htm">reverse_</a></tt> iterator generators, and expanded | ||||
|     <tt><a href="counting_iterator.htm">counting_iterator_generator</a></tt> to | ||||
|     cover all incrementable types. He edited most of the documentation, | ||||
|     sometimes heavily.<br> | ||||
|      <b><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy | ||||
|     Siek</a></b> contributed the <a href="transform_iterator.htm">transform | ||||
|     iterator</a> adaptor, the integer-only version of <tt><a href= | ||||
|     "counting_iterator.htm">counting_iterator_generator</a></tt>,  | ||||
|     the <a href="function_output_iterator.htm">function output iterator</a>  | ||||
|     adaptor, and most of the documentation.<br> | ||||
|      <b><a href="http://www.boost.org/people/john_potter.htm">John | ||||
|     Potter</a></b> contributed the <tt><a href= | ||||
|     "projection_iterator.htm">projection_</a></tt> and <tt><a href= | ||||
|     "filter_iterator.htm">filter_</a></tt> iterator generators and made some | ||||
|     simplifications to the main <tt><a href= | ||||
|     "#iterator_adaptor">iterator_adaptor</a></tt> template.<br> | ||||
|  | ||||
|  | ||||
|     <h2><a name="iterator_adaptor">Class template</a> | ||||
|     <tt>iterator_adaptor</tt></h2> | ||||
|     Implementing standard conforming iterators is a non-trivial task. There are | ||||
|     some fine points such as the interactions between an iterator and its | ||||
|     corresponding const_iterator, and there are myriad operators that should be | ||||
|     implemented but are easily forgotten or mishandled, such as | ||||
|     <tt>operator->()</tt>. Using <tt>iterator_adaptor</tt>, you can easily | ||||
|     implement an iterator class, and even more easily extend and <a href= | ||||
|     "../../more/generic_programming.html#adaptors">adapt</a> existing iterator | ||||
|     types. Moreover, it is easy to make a pair of interoperable <tt>const</tt> | ||||
|     and <tt>non-const</tt> iterators.  | ||||
|  | ||||
|     <p><tt>iterator_adaptor</tt> is declared like this: | ||||
| <pre> | ||||
| template <class Base, class Policies,  | ||||
|     class ValueOrNamedParams = typename std::iterator_traits<Base>::value_type, | ||||
|     class ReferenceOrNamedParams = <i>...(see below)</i>, | ||||
|     class PointerOrNamedParams = <i>...(see below)</i>, | ||||
|     class CategoryOrNamedParams = typename std::iterator_traits<Base>::iterator_category, | ||||
|     class DistanceOrNamedParams = typename std::iterator_traits<Base>::difference_type> | ||||
| struct iterator_adaptor; | ||||
| </pre> | ||||
|  | ||||
|     <h3><a name="template_parameters">Template Parameters</a></h3> | ||||
|  | ||||
|     <p>Although <tt>iterator_adaptor</tt> takes seven template parameters, | ||||
|     defaults have been carefully chosen to minimize the number of parameters | ||||
|     you must supply in most cases, especially if <tt>BaseType</tt> is an | ||||
|     iterator. | ||||
|  | ||||
|     <table border="1" summary="iterator_adaptor template parameters"> | ||||
|       <tr> | ||||
|         <th>Parameter | ||||
|  | ||||
|         <th>Description | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>BaseType</tt>  | ||||
|  | ||||
|         <td>The type being wrapped. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Policies</tt>  | ||||
|  | ||||
|         <td>A <a href="../../more/generic_programming.html#policy">policy | ||||
|         class</a> that supplies core functionality to the resulting iterator. A | ||||
|         detailed description can be found <a href="#policies">below</a>. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Value</tt>  | ||||
|  | ||||
|         <td>The <tt>value_type</tt> of the resulting iterator, unless const. If | ||||
|         Value is <tt>const X</tt> the | ||||
|         <tt>value_type</tt> will be (<i>non-</i><tt>const</tt>) <tt>X</tt><a href= | ||||
|         "#1">[1]</a>.<br> | ||||
|          <b>Default:</b> | ||||
|         <tt>std::iterator_traits<BaseType>::value_type</tt> <a href= | ||||
|         "#2">[2]</a> | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Reference</tt>  | ||||
|  | ||||
|         <td>The <tt>reference</tt> type of the resulting iterator, and in | ||||
|         particular, the result type of <tt>operator*()</tt>.<br> | ||||
|          <b>Default:</b> If <tt>Value</tt> is supplied, <tt>Value&</tt> is | ||||
|         used. Otherwise | ||||
|         <tt>std::iterator_traits<BaseType>::reference</tt> is used. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Pointer</tt>  | ||||
|  | ||||
|         <td>The <tt>pointer</tt> type of the resulting iterator, and in | ||||
|         particular, the result type of <tt>operator->()</tt>.<br> | ||||
|          <b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>, | ||||
|         otherwise <tt>std::iterator_traits<BaseType>::pointer</tt>. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Category</tt>  | ||||
|  | ||||
|         <td>The <tt>iterator_category</tt> type for the resulting iterator.<br> | ||||
|          <b>Default:</b> | ||||
|         <tt>std::iterator_traits<BaseType>::iterator_category</tt>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Distance</tt>  | ||||
|  | ||||
|         <td>The <tt>difference_type</tt> for the resulting iterator.<br> | ||||
|          <b>Default:</b> | ||||
|         <tt>std::iterator_traits<BaseType>::difference_type</tt>  | ||||
|  | ||||
|       <tr> | ||||
|          <td><tt>NamedParams</tt> | ||||
|  | ||||
|          <td>A list of named template parameters generated using the | ||||
|             <a href="#iterator_traits_generator"> | ||||
|             <tt>iterator_traits_generator</tt></a> class (see below). | ||||
|     </table> | ||||
|  | ||||
|     <h3><a name="named_template_parameters">Named Template Parameters</a></h3> | ||||
|      | ||||
|     With seven template parameters, providing arguments for | ||||
|     <tt>iterator_adaptor</tt> in the correct order can be challenging. | ||||
|     Also, often times one would like to specify the sixth or seventh | ||||
|     template parameter, but use the defaults for the third through | ||||
|     fifth. As a solution to these problems we provide a mechanism for | ||||
|     naming the last five template parameters, and providing them in | ||||
|     any order through the <tt>iterator_traits_generator</tt> class. | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| <a name="iterator_traits_generator">class iterator_traits_generator</a> | ||||
| { | ||||
| public: | ||||
|   template <class Value> | ||||
|   struct value_type : public <i>recursive magic</i> { }; | ||||
|  | ||||
|   template <class Reference> | ||||
|   struct reference : public <i>recursive magic</i> { }; | ||||
|  | ||||
|   template <class Pointer> | ||||
|   struct pointer : public <i>recursive magic</i> { }; | ||||
|  | ||||
|   template <class Distance> | ||||
|   struct difference_type : public <i>recursive magic</i> { }; | ||||
|  | ||||
|   template <class Category> | ||||
|   struct iterator_category : public <i>recursive magic</i> { }; | ||||
| }; | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     The <tt>iterator_traits_generator</tt> is used to create a list of | ||||
|     of template arguments. For example, suppose you want to set the | ||||
|     <tt>Reference</tt> and <tt>Category</tt> parameters, and use the | ||||
|     defaults for the rest. Then you can use the traits generator as | ||||
|     follows: | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| iterator_traits_generator::reference<foo>::category<std::input_iterator_tag> | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     This generated type can then be passed into the <tt>iterator_adaptor</tt> | ||||
|     class to replace any of the last five parameters. If you use the traits | ||||
|     generator in the <i>i</i>th parameter position, then the parameters <i>i</i> | ||||
|     through 7 will use the types specified in the generator. For example, the | ||||
|     following adapts <tt>foo_iterator</tt> to create an <a href= | ||||
|     "http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> with | ||||
|     <tt>reference</tt> type <tt>foo</tt>, and whose other traits are determined | ||||
|     according to the defaults described <a href="#template_parameters">above</a>. | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| iterator_adaptor<foo_iterator, foo_policies, | ||||
|     iterator_traits_generator | ||||
|     ::reference<foo> | ||||
|     ::iterator_category<std::input_iterator_tag> | ||||
| > | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|      | ||||
|     <h3><a name="policies">The Policies Class</a></h3> | ||||
|  | ||||
|     <p>The main task in using <tt>iterator_adaptor</tt> is creating an | ||||
|     appropriate <tt>Policies</tt> class. The <tt>Policies</tt> class will become | ||||
|     the functional heart of the resulting iterator, supplying the core | ||||
|     operations that determine its behavior. The <tt>iterator_adaptor</tt> | ||||
|     template defines all of the operators required of a <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access | ||||
|     Iterator</a> by dispatching to a <tt>Policies</tt> object. Your | ||||
|     <tt>Policies</tt> class must implement a subset of the core iterator | ||||
|     operations below corresponding to the iterator categories you want it to | ||||
|     support.<br> | ||||
|     <br> | ||||
|      | ||||
|  | ||||
|     <table border="1" summary="iterator_adaptor Policies operations"> | ||||
|       <caption> | ||||
|         <b>Core Iterator Operations</b><br> | ||||
|         <tt>T</tt>: adapted iterator type; <tt>p</tt>: object of type T; <tt>n</tt>: <tt>T::size_type</tt>; <tt>x</tt>: <tt>T::difference_type</tt>; <tt>p1</tt>, <tt>p2</tt>: iterators | ||||
|       </caption> | ||||
|  | ||||
|       <tr> | ||||
|         <th>Operation | ||||
|  | ||||
|         <th>Effects | ||||
|  | ||||
|         <th>Implements Operations | ||||
|  | ||||
|         <th>Required for Iterator Categories | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>dereference</tt>  | ||||
|  | ||||
|         <td>returns an element of the iterator's <tt>reference</tt> type | ||||
|          | ||||
|         <td><tt>*p</tt>, <tt>p[n]</tt> | ||||
|  | ||||
|         <td rowspan="3"><a href= | ||||
|         "http://www.sgi.com/tech/stl/InputIterator.html">Input</a>/ <a href= | ||||
|         "http://www.sgi.com/tech/stl/OutputIterator.html">Output</a>/ <a href= | ||||
|         "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward</a>/ <a | ||||
|         href= | ||||
|         "http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional</a>/ | ||||
|         <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
|         Access</a>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>equal</tt>  | ||||
|  | ||||
|         <td>tests the iterator for equality | ||||
|  | ||||
|         <td><tt>p1 == p2</tt>, <tt>p1 != p2</tt> | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>increment</tt>  | ||||
|  | ||||
|         <td>increments the iterator | ||||
|  | ||||
|         <td><tt>++p</tt>, <tt>p++</tt> | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>decrement</tt>  | ||||
|  | ||||
|         <td>decrements the iterator | ||||
|  | ||||
|         <td><tt>--p</tt>, <tt>p--</tt> | ||||
|  | ||||
|         <td><a href= | ||||
|         "http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional</a>/ | ||||
|         <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
|         Access</a>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>less</tt>  | ||||
|  | ||||
|         <td>imposes a <a href= | ||||
|         "http://www.sgi.com/tech/stl/StrictWeakOrdering.html">Strict Weak | ||||
|         Ordering</a> relation on iterators | ||||
|  | ||||
|         <td>  | ||||
|            <tt>p1 < p2</tt>, | ||||
|            <tt>p1 <= p2</tt>, | ||||
|            <tt>p1 > p2</tt>, | ||||
|            <tt>p1 >= p2</tt> | ||||
|  | ||||
|         <td rowspan="3"><a href= | ||||
|         "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
|         Access</a>  | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>distance</tt>  | ||||
|  | ||||
|         <td>measures the distance between iterators | ||||
|  | ||||
|         <td><tt>p1 - p2</tt> | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>advance</tt>  | ||||
|  | ||||
|         <td>adds an integer offset to iterators | ||||
|  | ||||
|         <td> | ||||
| <tt>p + x</tt>, | ||||
| <tt>x + p</tt>, | ||||
| <tt>p += x</tt>, | ||||
| <tt>p - x</tt>, | ||||
| <tt>p -= x</tt> | ||||
|          | ||||
|     </table> | ||||
|  | ||||
|     <p>The library also supplies a "trivial" policy class, | ||||
|     <tt>default_iterator_policies</tt>, which implements all seven of the core | ||||
|     operations in the usual way. If you wish to create an iterator adaptor that | ||||
|     only changes a few of the base type's behaviors, then you can derive your | ||||
|     new policy class from <tt>default_iterator_policies</tt> to avoid retyping | ||||
|     the usual behaviors. You should also look at | ||||
|     <tt>default_iterator_policies</tt> as the ``boilerplate'' for your own | ||||
|     policy classes, defining functions with the same interface. This is the | ||||
|     definition of <tt>default_iterator_policies</tt>:<br> | ||||
|     <br> | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| struct <a name="default_iterator_policies">default_iterator_policies</a> | ||||
| { | ||||
|   template <class Reference, class BaseType> | ||||
|   Reference dereference(type<Reference>, const BaseType& x) const | ||||
|     { return *x; } | ||||
|  | ||||
|   template <class BaseType> | ||||
|   static void increment(BaseType& x) | ||||
|     { ++x; } | ||||
|  | ||||
|   template <class BaseType1, class BaseType2> | ||||
|   bool equal(BaseType1& x, BaseType2& y) const | ||||
|     { return x == y; } | ||||
|  | ||||
|   template <class BaseType> | ||||
|   static void decrement(BaseType& x) | ||||
|     { --x; } | ||||
|  | ||||
|   template <class BaseType, class DifferenceType> | ||||
|   static void advance(BaseType& x, DifferenceType n) | ||||
|     { x += n; } | ||||
|  | ||||
|   template <class Difference, class BaseType1, class BaseType2> | ||||
|   Difference distance(type<Difference>, BaseType1& x, BaseType2& y) const | ||||
|     { return y - x; } | ||||
|  | ||||
|   template <class BaseType1, class BaseType2> | ||||
|   bool less(BaseType1& x, BaseType2& y) const | ||||
|     { return x < y; } | ||||
| }; | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <p>Template member functions are used throughout | ||||
|     <tt>default_iterator_policies</tt> so that it can be employed with a wide | ||||
|     range of iterators. If we had used concrete types above, we'd have tied the | ||||
|     usefulness of <tt>default_iterator_policies</tt> to a particular range of | ||||
|     adapted iterators. If you follow the same pattern with your | ||||
|     <tt>Policies</tt> classes, you can use them to generate more specialized | ||||
|     adaptors along the lines of <a href="#specialized_adaptors">those supplied by this library</a>. | ||||
|  | ||||
|     <h3><a name="additional_members">Additional Members</a></h3> | ||||
|     In addition to all of the member functions required of a <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access | ||||
|     Iterator</a>, the <tt>iterator_adaptor</tt> class template defines the | ||||
|     following members. <br> | ||||
|      <br> | ||||
|       | ||||
|  | ||||
|     <table border="1" summary="additional iterator_adaptor members"> | ||||
|       <tr> | ||||
|         <td><tt>explicit iterator_adaptor(const Base&, const Policies& = | ||||
|         Policies())</tt> | ||||
|          <br><br> | ||||
|          Construct an adapted iterator from a base object and a policies | ||||
|          object. As this constructor is <tt>explicit</tt>, it does not | ||||
|          provide for implicit conversions from the <tt>Base</tt> type to | ||||
|          the iterator adaptor. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>template <class B, class V, class R, class P><br> | ||||
|          iterator_adaptor(const | ||||
|         iterator_adaptor<B,Policies,V,R,P,Category,Distance>&)</tt> | ||||
|         <br><br> | ||||
|          This constructor allows for conversion from non-<tt>const</tt> to | ||||
|         constant adapted iterators. See <a href= | ||||
|         "#iterator_interactions">below</a> for more details.<br> | ||||
|          Requires: <tt>B</tt> is convertible to <tt>Base</tt>. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>base_type base() const;</tt> | ||||
|          <br><br> | ||||
|          Return a copy of the base object. | ||||
|     </table> | ||||
|  | ||||
|     <h3><a name="example">Example</a></h3> | ||||
|  | ||||
|     <p>It is often useful to automatically apply some function to the value | ||||
|     returned by dereferencing an iterator. The <a href= | ||||
|     "./transform_iterator.htm">transform iterator</a> makes it easy to create | ||||
|     an iterator adaptor which does just that. Here we will show how easy it is | ||||
|     to implement the transform iterator using the <tt>iterator_adaptor</tt> | ||||
|     template. | ||||
|  | ||||
|     <p>We want to be able to adapt a range of iterators and functions, so the | ||||
|     policies class will have a template parameter for the function type and it | ||||
|     will have a data member of that type. We know that the function takes one | ||||
|     argument and that we'll need to be able to deduce the <tt>result_type</tt> | ||||
|     of the function so we can use it for the adapted iterator's | ||||
|     <tt>value_type</tt>. <a href= | ||||
|     "http://www.sgi.com/Technology/STL/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a> | ||||
|     is the <a href="../../more/generic_programming.html#concept">Concept</a> | ||||
|     that fulfills those requirements. | ||||
|  | ||||
|     <p>To implement a transform iterator we will only change one of the base | ||||
|     iterator's behaviors, so the <tt>transform_iterator_policies</tt> class can | ||||
|     inherit the rest from <tt>default_iterator_policies</tt>. We will define | ||||
|     the <tt>dereference()</tt> member function, which is used to implement | ||||
|     <tt>operator*()</tt> of the adapted iterator. The implementation will | ||||
|     dereference the base iterator and apply the function object. The | ||||
|     <tt>type<Reference></tt> parameter is used to convey the appropriate | ||||
|     return type. The complete code for <tt>transform_iterator_policies</tt> | ||||
|     is:<br> | ||||
|     <br> | ||||
|  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
|   template <class AdaptableUnaryFunction> | ||||
|   struct transform_iterator_policies : public default_iterator_policies | ||||
|   { | ||||
|     transform_iterator_policies() { } | ||||
|  | ||||
|     transform_iterator_policies(const AdaptableUnaryFunction& f) | ||||
|       : m_f(f) { } | ||||
|  | ||||
|     template <class Reference, class BaseIterator> | ||||
|     Reference dereference(type<Reference>, const BaseIterator& i) const | ||||
|       { return m_f(*i); } | ||||
|  | ||||
|     AdaptableUnaryFunction m_f; | ||||
|   }; | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <p>The next step is to use the <tt>iterator_adaptor</tt> template to | ||||
|     construct the transform iterator type. The nicest way to package the | ||||
|     construction of the transform iterator is to create a <a href= | ||||
|     "../../more/generic_programming.html#type_generator">type generator</a>. | ||||
|     The first template parameter to the generator will be the type of the | ||||
|     function object and the second will be the base iterator type. We use | ||||
|     <tt>iterator_adaptor</tt> to define the transform iterator type as a nested | ||||
|     <tt>typedef</tt> inside the <tt>transform_iterator_generator</tt> class. | ||||
|     Because the function may return by-value, we must limit the | ||||
|     <tt>iterator_category</tt> to <a href= | ||||
|     "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>, and | ||||
|     the iterator's <tt>reference</tt> type cannot be a true reference (the | ||||
|     standard allows this for input iterators), so in this case we can use few | ||||
|     of <tt>iterator_adaptor</tt>'s default template arguments.<br> | ||||
|     <br> | ||||
|  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class AdaptableUnaryFunction, class Iterator> | ||||
| struct transform_iterator_generator | ||||
| { | ||||
|     typedef typename AdaptableUnaryFunction::result_type value_type; | ||||
| public: | ||||
|     typedef iterator_adaptor<Iterator,  | ||||
|         transform_iterator_policies<AdaptableUnaryFunction>, | ||||
|         value_type, value_type, value_type*, std::input_iterator_tag> | ||||
|       type; | ||||
| }; | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <p>As a finishing touch, we will create an <a href= | ||||
|     "../../more/generic_programming.html#object_generator">object generator</a> | ||||
|     for the transform iterator. This is a function that makes it more | ||||
|     convenient to create a transform iterator.<br> | ||||
|     <br> | ||||
|  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class AdaptableUnaryFunction, class Iterator> | ||||
| typename transform_iterator_generator<AdaptableUnaryFunction,Iterator>::type | ||||
| make_transform_iterator(Iterator base, | ||||
|                         const AdaptableUnaryFunction& f = AdaptableUnaryFunction()) | ||||
| { | ||||
|     typedef typename transform_iterator_generator<AdaptableUnaryFunction, | ||||
|       Iterator>::type result_t; | ||||
|     return result_t(base, f); | ||||
| } | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <p>Here is an example that shows how to use a transform iterator to iterate | ||||
|     through a range of numbers, multiplying each of them by 2 and printing the | ||||
|     result to standard output.<br> | ||||
|     <br> | ||||
|  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| #include <functional> | ||||
| #include <algorithm> | ||||
| #include <iostream> | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; | ||||
|   const int N = sizeof(x)/sizeof(int); | ||||
|   std::cout << "multiplying the array by 2:" << std::endl; | ||||
|   std::copy(boost::make_transform_iterator(x, std::bind1st(std::multiplies<int>(), 2)), | ||||
|       boost::make_transform_iterator(x + N, std::bind1st(std::multiplies<int>(), 2)), | ||||
|       std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|   return 0; | ||||
| } | ||||
| </pre> | ||||
|       This output is:  | ||||
| <pre> | ||||
| 2 4 6 8 10 12 14 16 | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3><a name="iterator_interactions">Iterator Interactions</a></h3> | ||||
|  | ||||
|     <p>C++ allows <tt>const</tt> and non-<tt>const</tt> pointers to interact in | ||||
|     the following intuitive ways: | ||||
|  | ||||
|     <ul> | ||||
|       <li>a non-<tt>const</tt> pointer to <tt>T</tt> can be implicitly | ||||
|       converted to a <tt>const</tt> pointer to <tt>T</tt>. | ||||
|  | ||||
|       <li><tt>const</tt> and non-<tt>const</tt> pointers to <tt>T</tt> can be | ||||
|       freely mixed in comparison expressions. | ||||
|  | ||||
|       <li><tt>const</tt> and non-<tt>const</tt> pointers to <tt>T</tt> can be | ||||
|       freely subtracted, in any order. | ||||
|     </ul> | ||||
|  | ||||
|     Getting user-defined iterators to work together that way is nontrivial (see | ||||
|     <a href="reverse_iterator.htm#interactions">here</a> for an example of where | ||||
|     the C++ standard got it wrong), but <tt>iterator_adaptor</tt> can make it | ||||
|     easy. The rules are as follows: | ||||
|  | ||||
|     <ul> | ||||
|       <li><a name="interoperable">Adapted iterators that share the same <tt>Policies</tt>, | ||||
|       <tt>Category</tt>, and <tt>Distance</tt> parameters are called | ||||
|       <i>interoperable</i>.</a> | ||||
|  | ||||
|       <li>An adapted iterator can be implicitly converted to any other adapted | ||||
|       iterator with which it is interoperable, so long as the <tt>Base</tt> | ||||
|       type of the source iterator can be converted to the <tt>Base</tt> type of | ||||
|       the target iterator. | ||||
|  | ||||
|       <li>Interoperable iterators can be freely mixed in comparison expressions | ||||
|       so long as the <tt>Policies</tt> class has <tt>equal</tt> (and, for | ||||
|       random access iterators, <tt>less</tt>) members that can accept both | ||||
|       <tt>Base</tt> types in either order. | ||||
|  | ||||
|       <li>Interoperable iterators can be freely mixed in subtraction | ||||
|       expressions so long as the <tt>Policies</tt> class has a | ||||
|       <tt>distance</tt> member that can accept both <tt>Base</tt> types in | ||||
|       either order. | ||||
|     </ul> | ||||
|  | ||||
|     <h4>Example</h4> | ||||
|      | ||||
|     <p>The <a href="projection_iterator.htm">Projection Iterator</a> adaptor is similar to the <a | ||||
| href="./transform_iterator.htm">transform iterator adaptor</a> in that | ||||
| its <tt>operator*()</tt> applies some function to the result of | ||||
| dereferencing the base iterator and then returns the result. The | ||||
| difference is that the function must return a reference to some | ||||
| existing object (for example, a data member within the | ||||
| <tt>value_type</tt> of the base iterator).  | ||||
|  | ||||
|     <p> | ||||
| The <a | ||||
|     href="projection_iterator.htm#projection_iterator_pair_generator">projection_iterator_pair_generator</a> template | ||||
|     is a special two-<a href="../../more/generic_programming.html#type_generator">type generator</a> for mutable and constant versions of a | ||||
|     projection iterator. It is defined as follows: | ||||
| <blockquote> | ||||
| <pre> | ||||
| template <class AdaptableUnaryFunction, class Iterator, class ConstIterator> | ||||
| struct projection_iterator_pair_generator { | ||||
|     typedef typename AdaptableUnaryFunction::result_type value_type; | ||||
|     typedef projection_iterator_policies<AdaptableUnaryFunction> policies; | ||||
| public: | ||||
|     typedef iterator_adaptor<Iterator,policies,value_type> iterator; | ||||
|     typedef iterator_adaptor<ConstIterator,policies,value_type, | ||||
|         const value_type&,const value_type*> const_iterator; | ||||
| }; | ||||
| </pre> | ||||
| </blockquote> | ||||
|  | ||||
| <p>It is assumed that the <tt>Iterator</tt> and <tt>ConstIterator</tt> arguments are corresponding mutable | ||||
| and constant iterators. <ul> | ||||
| <li> | ||||
| Clearly, then, the | ||||
| <tt>projection_iterator_pair_generator</tt>'s <tt>iterator</tt> and | ||||
| <tt>const_iterator</tt> are <a href="#interoperable">interoperable</a>, since | ||||
| they share the same <tt>Policies</tt> and since <tt>Category</tt> and | ||||
| <tt>Distance</tt> as supplied by <tt>std::iterator_traits</tt> through the | ||||
| <a href="#template_parameters">default template parameters</a> to | ||||
| <tt>iterator_adaptor</tt> should be the same. | ||||
|  | ||||
| <li>Since <tt>Iterator</tt> can presumably be converted to | ||||
| <tt>ConstIterator</tt>, the projection <tt>iterator</tt> will be convertible to | ||||
| the projection <tt>const_iterator</tt>. | ||||
|  | ||||
| <li> Since <tt>projection_iterator_policies</tt> implements only the | ||||
| <tt>dereference</tt> operation, and inherits all other behaviors from <tt><a | ||||
| href="#default_iterator_policies">default_iterator_policies</a></tt>, which has | ||||
| fully-templatized <tt>equal</tt>, <tt>less</tt>, and <tt>distance</tt> | ||||
| operations, the <tt>iterator</tt> and <tt>const_iterator</tt> can be freely | ||||
| mixed in comparison and subtraction expressions. | ||||
|  | ||||
| </ul> | ||||
|  | ||||
|     <h3><a name="challenge">Challenge</a></h3> | ||||
|  | ||||
|     <p>There is an unlimited number of ways the <tt>iterator_adaptors</tt> | ||||
|     class can be used to create iterators. One interesting exercise would be to | ||||
|     re-implement the iterators of <tt>std::list</tt> and <tt>std::slist</tt> | ||||
|     using <tt>iterator_adaptors</tt>, where the adapted <tt>Iterator</tt> types | ||||
|     would be node pointers. | ||||
|  | ||||
|     <h3><a name="concept_model">Concept Model</a></h3> | ||||
|     Depending on the <tt>Base</tt> and <tt>Policies</tt> template parameters, | ||||
|     an <tt>iterator_adaptor</tt> can be a <a href= | ||||
|     "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>, <a | ||||
|     href="http://www.sgi.com/tech/stl/ForwardIterator.html">Forward | ||||
|     Iterator</a>, <a href= | ||||
|     "http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional | ||||
|     Iterator</a>, or <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access | ||||
|     Iterator</a>.  | ||||
|  | ||||
|     <h3><a name="declaration_synopsis">Declaration Synopsis</a></h3> | ||||
| <pre> | ||||
| template <class Base, class Policies,  | ||||
|     class Value = typename std::iterator_traits<Base>::value_type, | ||||
|     class Reference = <i>...(see below)</i>, | ||||
|     class Pointer = <i>...(see below)</i>, | ||||
|     class Category = typename std::iterator_traits<Base>::iterator_category, | ||||
|     class Distance = typename std::iterator_traits<Base>::difference_type | ||||
|          > | ||||
| struct iterator_adaptor | ||||
| { | ||||
|     typedef Distance difference_type; | ||||
|     typedef typename boost::remove_const<Value>::type value_type; | ||||
|     typedef Pointer pointer; | ||||
|     typedef Reference reference; | ||||
|     typedef Category iterator_category; | ||||
|     typedef Base base_type; | ||||
|     typedef Policies policies_type; | ||||
|  | ||||
|     iterator_adaptor(); | ||||
|     explicit iterator_adaptor(const Base&, const Policies& = Policies()); | ||||
|  | ||||
|     base_type base() const; | ||||
|  | ||||
|     template <class B, class V, class R, class P> | ||||
|     iterator_adaptor( | ||||
|         const iterator_adaptor<B,Policies,V,R,P,Category,Distance>&); | ||||
|  | ||||
|     reference operator*() const; | ||||
|     <i>operator_arrow_result_type</i> operator->() const; <a href= | ||||
| "#3">[3]</a> | ||||
|     <i>value_type</i> operator[](difference_type n) const; <a href="#3">[4]</a> | ||||
|  | ||||
|     iterator_adaptor& operator++(); | ||||
|     iterator_adaptor& operator++(int); | ||||
|     iterator_adaptor& operator--(); | ||||
|     iterator_adaptor& operator--(int); | ||||
|  | ||||
|     iterator_adaptor& operator+=(difference_type n); | ||||
|     iterator_adaptor& operator-=(difference_type n); | ||||
|  | ||||
|     iterator_adaptor& operator-(Distance x) const; | ||||
| }; | ||||
|  | ||||
| template <class B, class P, class V, class R, class Ptr,  | ||||
|     class C, class D1, class D2> | ||||
| iterator_adaptor<B,P,V,R,Ptr,C,D1> | ||||
| operator+(iterator_adaptor<B,P,V,R,Ptr,C,D1>, D2); | ||||
|  | ||||
| template <class B, class P, class V, class R, class Ptr, | ||||
|     class C, class D1, class D2> | ||||
| iterator_adaptor<B,P,V,R,P,C,D1> | ||||
| operator+(D2, iterator_adaptor<B,P,V,R,Ptr,C,D1> p); | ||||
|  | ||||
| template <class B1, class B2, class P, class V1, class V2, | ||||
|     class R1, class R2, class P1, class P2, class C, class D> | ||||
| Distance operator-(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,  | ||||
|                    const iterator_adaptor<B2,P,V2,R2,P2,C,D>&); | ||||
|  | ||||
| template <class B1, class B2, class P, class V1, class V2, | ||||
|     class R1, class R2, class P1, class P2, class C, class D> | ||||
| bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,  | ||||
|                 const iterator_adaptor<B2,P,V2,R2,P2,C,D>&); | ||||
|  | ||||
| // and similarly for operators !=, <, <=, >=, > | ||||
| </pre> | ||||
|  | ||||
|     <h3><a name="notes">Notes</a></h3> | ||||
|  | ||||
|     <p><a name="1">[1]</a> The standard specifies that the <tt>value_type</tt> | ||||
|     of <tt>const</tt> iterators to <tt>T</tt> (e.g. <tt>const T*</tt>) is | ||||
|     <tt><i>non-</i>const T</tt>, while the <tt>pointer</tt> and | ||||
|     <tt>reference</tt> types for all <a href= | ||||
|     "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterators</a> are | ||||
|     <tt>const T*</tt> and <tt>const T&</tt>, respectively. Stripping the | ||||
|     <tt>const</tt>-ness of <tt>Value</tt> allows you to easily | ||||
|     make a <tt>const</tt> iterator adaptor by supplying a <tt>const</tt> type | ||||
|     for <tt>Value</tt>, and allowing the defaults for the <tt>Pointer</tt> and | ||||
|     <tt>Reference</tt> parameters to take effect. Although compilers that don't | ||||
|     support partial specialization won't strip <tt>const</tt> for you, having a | ||||
|     <tt>const value_type</tt> is often harmless in practice. | ||||
|  | ||||
|     <p><a name="2">[2]</a> If your compiler does not support partial | ||||
|     specialization and the base iterator is a builtin pointer type, you | ||||
|     will not be able to use the default for <tt>Value</tt> and will have to | ||||
|     specify this type explicitly. | ||||
|  | ||||
|     <p><a name="3">[3]</a> The result type for the <tt>operator->()</tt> | ||||
|     depends on the category and value type of the iterator and is somewhat | ||||
|     complicated to describe. But be assured, it works in a stardard conforming | ||||
|     fashion, providing access to members of the objects pointed to by the | ||||
|     iterator. | ||||
|  | ||||
|     <p><a name="4">[4]</a> The result type of <tt>operator[]()</tt> is | ||||
|     <tt>value_type</tt> instead of <tt>reference</tt> as might be expected. | ||||
|     There are two reasons for this choice. First, the C++ standard only | ||||
|     requires that the return type of an arbitrary <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access | ||||
|     Iterator</a>'s <tt>operator[]</tt>be ``convertible to T'' (Table 76), so | ||||
|     when adapting an arbitrary base iterator we may not have a reference to | ||||
|     return. Second, and more importantly, for certain kinds of iterators, | ||||
|     returning a reference could cause serious memory problems due to the | ||||
|     reference being bound to a temporary object whose lifetime ends inside of | ||||
|     the <tt>operator[]</tt>. | ||||
|     <hr> | ||||
|  | ||||
|     <p>Revised  | ||||
|     <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->09 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14894" --> | ||||
|  | ||||
|  | ||||
|     <p>© Copyright Dave Abrahams and Jeremy Siek 2001. 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.  | ||||
|  | ||||
| <body> | ||||
| This documentation moved to <a href="../iterator/doc/index.html">../iterator/doc/index.html</a>. | ||||
| </body> | ||||
|  | ||||
|     <!--  LocalWords:  HTML html charset alt gif abrahams htm const | ||||
|         incrementable david abrahams | ||||
|          --> | ||||
|       | ||||
|     <!--  LocalWords:  jeremy siek mishandled interoperable typename struct Iter iter src | ||||
|          --> | ||||
|       | ||||
|     <!--  LocalWords:  int bool ForwardIterator BidirectionalIterator BaseIterator | ||||
|          --> | ||||
|       | ||||
|     <!--  LocalWords:  RandomAccessIterator DifferenceType AdaptableUnaryFunction | ||||
|          --> | ||||
|       | ||||
|     <!--  LocalWords:  iostream hpp sizeof InputIterator constness ConstIterator | ||||
|          David Abrahams | ||||
|          --> | ||||
| </html> | ||||
|  | ||||
|   | ||||
| @@ -1,210 +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 | ||||
| //  04 Mar 2001 Patches for Intel C++ (Dave Abrahams) | ||||
| //  19 Feb 2001 Take advantage of improved iterator_traits to do more tests | ||||
| //              on MSVC. Reordered some #ifdefs for coherency. | ||||
| //              (David Abrahams) | ||||
| //  13 Feb 2001 Test new VC6 workarounds (David Abrahams) | ||||
| //  11 Feb 2001 Final fixes for Borland (David Abrahams) | ||||
| //  11 Feb 2001 Some fixes for Borland get it closer on that compiler | ||||
| //              (David Abrahams) | ||||
| //  07 Feb 2001 More comprehensive testing; factored out static tests for | ||||
| //              better reuse (David Abrahams) | ||||
| //  21 Jan 2001 Quick fix to my_iterator, which wasn't returning a | ||||
| //              reference type from operator* (David Abrahams) | ||||
| //  19 Jan 2001 Initial version with iterator operators (David Abrahams) | ||||
|  | ||||
| #include <boost/detail/iterator.hpp> | ||||
| #include <boost/type_traits.hpp> | ||||
| #include <boost/operators.hpp> | ||||
| #include <boost/static_assert.hpp> | ||||
| #include <iterator> | ||||
| #include <vector> | ||||
| #include <list> | ||||
| #include <cassert> | ||||
| #include <iostream> | ||||
|  | ||||
| // An iterator for which we can get traits. | ||||
| struct my_iterator1 | ||||
|     : boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&> | ||||
| { | ||||
|     my_iterator1(const char* p) : m_p(p) {} | ||||
|      | ||||
|     bool operator==(const my_iterator1& rhs) const | ||||
|         { return this->m_p == rhs.m_p; } | ||||
|  | ||||
|     my_iterator1& operator++() { ++this->m_p; return *this; } | ||||
|     const char& operator*() { return *m_p; } | ||||
|  private: | ||||
|     const char* m_p; | ||||
| }; | ||||
|  | ||||
| // Used to prove that we don't require std::iterator<> in the hierarchy under | ||||
| // MSVC6, and that we can compute all the traits for a standard-conforming UDT | ||||
| // iterator. | ||||
| struct my_iterator2 | ||||
|     : boost::equality_comparable<my_iterator2 | ||||
|     , boost::incrementable<my_iterator2 | ||||
|     , boost::dereferenceable<my_iterator2,const char*> > > | ||||
| { | ||||
|     typedef char value_type; | ||||
|     typedef long difference_type; | ||||
|     typedef const char* pointer; | ||||
|     typedef const char& reference; | ||||
|     typedef std::forward_iterator_tag iterator_category; | ||||
|      | ||||
|     my_iterator2(const char* p) : m_p(p) {} | ||||
|      | ||||
|     bool operator==(const my_iterator2& rhs) const | ||||
|         { return this->m_p == rhs.m_p; } | ||||
|  | ||||
|     my_iterator2& operator++() { ++this->m_p; return *this; } | ||||
|     const char& operator*() { return *m_p; } | ||||
|  private: | ||||
|     const char* m_p; | ||||
| }; | ||||
|  | ||||
| // Used to prove that we're not overly confused by the existence of | ||||
| // std::iterator<> in the hierarchy under MSVC6 - we should find that | ||||
| // boost::detail::iterator_traits<my_iterator3>::difference_type is int. | ||||
| struct my_iterator3 : my_iterator1 | ||||
| { | ||||
|     typedef int difference_type; | ||||
|     my_iterator3(const char* p) : my_iterator1(p) {} | ||||
| }; | ||||
|  | ||||
| template <class Iterator, | ||||
|     class value_type, class difference_type, class pointer, class reference, class category> | ||||
| struct non_portable_tests | ||||
| { | ||||
|     // Unfortunately, the VC6 standard library doesn't supply these :( | ||||
|     BOOST_STATIC_ASSERT(( | ||||
|         boost::is_same< | ||||
|         typename boost::detail::iterator_traits<Iterator>::pointer, | ||||
|         pointer | ||||
|         >::value)); | ||||
|      | ||||
|     BOOST_STATIC_ASSERT(( | ||||
|         boost::is_same< | ||||
|         typename boost::detail::iterator_traits<Iterator>::reference, | ||||
|         reference | ||||
|         >::value)); | ||||
| }; | ||||
|  | ||||
| template <class Iterator, | ||||
|     class value_type, class difference_type, class pointer, class reference, class category> | ||||
| struct portable_tests | ||||
| { | ||||
|     BOOST_STATIC_ASSERT(( | ||||
|         boost::is_same< | ||||
|         typename boost::detail::iterator_traits<Iterator>::difference_type, | ||||
|         difference_type | ||||
|         >::value)); | ||||
|      | ||||
|     BOOST_STATIC_ASSERT(( | ||||
|         boost::is_same< | ||||
|         typename boost::detail::iterator_traits<Iterator>::iterator_category, | ||||
|         category | ||||
|         >::value)); | ||||
| }; | ||||
|  | ||||
| // Test iterator_traits | ||||
| template <class Iterator, | ||||
|     class value_type, class difference_type, class pointer, class reference, class category> | ||||
| struct input_iterator_test | ||||
|     : portable_tests<Iterator,value_type,difference_type,pointer,reference,category> | ||||
| { | ||||
|     BOOST_STATIC_ASSERT(( | ||||
|         boost::is_same< | ||||
|         typename boost::detail::iterator_traits<Iterator>::value_type, | ||||
|         value_type | ||||
|         >::value)); | ||||
| }; | ||||
|  | ||||
| template <class Iterator, | ||||
|     class value_type, class difference_type, class pointer, class reference, class category> | ||||
| struct non_pointer_test | ||||
|     : input_iterator_test<Iterator,value_type,difference_type,pointer,reference,category> | ||||
|       , non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category> | ||||
| { | ||||
| }; | ||||
|  | ||||
| template <class Iterator, | ||||
|     class value_type, class difference_type, class pointer, class reference, class category> | ||||
| struct maybe_pointer_test | ||||
|     : portable_tests<Iterator,value_type,difference_type,pointer,reference,category> | ||||
| #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|       , non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category> | ||||
| #endif | ||||
| { | ||||
| }; | ||||
|  | ||||
| input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag> | ||||
|         istream_iterator_test; | ||||
|  | ||||
| //  | ||||
| #if defined(__BORLANDC__) && !defined(__SGI_STL_PORT) | ||||
| typedef ::std::char_traits<char>::off_type distance; | ||||
| non_pointer_test<std::ostream_iterator<int>,int, | ||||
|     distance,int*,int&,std::output_iterator_tag> ostream_iterator_test; | ||||
| #elif defined(BOOST_MSVC_STD_ITERATOR) | ||||
| non_pointer_test<std::ostream_iterator<int>, | ||||
|     int, void, void, void, std::output_iterator_tag> | ||||
|         ostream_iterator_test; | ||||
| #else | ||||
| non_pointer_test<std::ostream_iterator<int>, | ||||
|     void, void, void, void, std::output_iterator_tag> | ||||
|         ostream_iterator_test; | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef __KCC | ||||
|   typedef long std_list_diff_type; | ||||
| #else | ||||
|   typedef std::ptrdiff_t std_list_diff_type; | ||||
| #endif | ||||
| non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag> | ||||
|         list_iterator_test; | ||||
|  | ||||
| maybe_pointer_test<std::vector<int>::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag> | ||||
|         vector_iterator_test; | ||||
|  | ||||
| maybe_pointer_test<int*, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag> | ||||
|         int_pointer_test; | ||||
|  | ||||
| non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forward_iterator_tag> | ||||
|        my_iterator1_test; | ||||
|                      | ||||
| non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag> | ||||
|        my_iterator2_test; | ||||
|                      | ||||
| non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag> | ||||
|        my_iterator3_test; | ||||
|                      | ||||
| int main() | ||||
| { | ||||
|     char chars[100]; | ||||
|     int ints[100]; | ||||
|      | ||||
|     for (std::ptrdiff_t length = 3; length < 100; length += length / 3) | ||||
|     { | ||||
|         std::list<int> l(length); | ||||
|         assert(boost::detail::distance(l.begin(), l.end()) == length); | ||||
|          | ||||
|         std::vector<int> v(length); | ||||
|         assert(boost::detail::distance(v.begin(), v.end()) == length); | ||||
|  | ||||
|         assert(boost::detail::distance(&ints[0], ints + length) == length); | ||||
|         assert(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length); | ||||
|         assert(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length); | ||||
|         assert(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length); | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| @@ -1,24 +1,36 @@ | ||||
| //  Demonstrate and test boost/operators.hpp on std::iterators  --------------// | ||||
|  | ||||
| //  (C) Copyright Jeremy Siek 1999. 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. | ||||
| //  (C) Copyright Jeremy Siek 1999. | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org for most recent version including documentation. | ||||
|  | ||||
| //  Revision History | ||||
| //  29 May 01 Factored implementation, added comparison tests, use Test Tools | ||||
| //            library (Daryle Walker) | ||||
| //  12 Dec 99 Initial version with iterator operators (Jeremy Siek) | ||||
|  | ||||
| #include <string> | ||||
| #include <iostream> | ||||
| using namespace std; | ||||
| #define  BOOST_INCLUDE_MAIN | ||||
| #include <boost/test/test_tools.hpp>  // for main | ||||
|  | ||||
| #include <boost/operators.hpp> | ||||
| using namespace boost; | ||||
| #include <boost/config.hpp>     // for BOOST_STATIC_CONSTANT | ||||
| #include <boost/cstdlib.hpp>    // for boost::exit_success | ||||
| #include <boost/operators.hpp>  // for boost::random_access_iterator_helper | ||||
|  | ||||
| #include <cstddef>    // for std::ptrdiff_t, std::size_t | ||||
| #include <cstring>    // for std::strcmp | ||||
| #include <iostream>   // for std::cout (std::endl, ends, and flush indirectly) | ||||
| #include <string>     // for std::string | ||||
| #include <sstream>    // for std::stringstream | ||||
|  | ||||
| # ifdef BOOST_NO_STDC_NAMESPACE | ||||
|     namespace std { using ::strcmp; } | ||||
| # endif | ||||
|  | ||||
|  | ||||
| // Iterator test class | ||||
| template <class T, class R, class P> | ||||
| struct test_iter | ||||
|   : public boost::random_access_iterator_helper< | ||||
| @@ -29,7 +41,7 @@ struct test_iter | ||||
|   typedef std::ptrdiff_t Distance; | ||||
|  | ||||
| public: | ||||
|   test_iter(T* i) : _i(i) { } | ||||
|   explicit test_iter(T* i =0) : _i(i) { } | ||||
|   test_iter(const self& x) : _i(x._i) { } | ||||
|   self& operator=(const self& x) { _i = x._i; return *this; } | ||||
|   Reference operator*() const { return *_i; } | ||||
| @@ -43,127 +55,270 @@ public: | ||||
|     return x._i - y._i;  | ||||
|   } | ||||
| protected: | ||||
|   T* _i; | ||||
|   P _i; | ||||
| }; | ||||
|  | ||||
|  | ||||
| int | ||||
| main() | ||||
| // Iterator operator testing classes | ||||
| class test_opr_base | ||||
| { | ||||
|   string array[] = { "apple", "orange", "pear", "peach", "grape", "plum"  }; | ||||
|   { | ||||
|     test_iter<string,string&,string*> i = array,  | ||||
|       ie = array + sizeof(array)/sizeof(string); | ||||
| protected: | ||||
|     // Test data and types | ||||
|     BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u ); | ||||
|  | ||||
|     // Tests for all of the operators added by random_access_iterator_helper | ||||
|     typedef std::string  fruit_array_type[ fruit_length ]; | ||||
|  | ||||
|     // test i++ | ||||
|     while (i != ie) | ||||
|       cout << *i++ << " "; | ||||
|     cout << endl; | ||||
|     i = array; | ||||
|     static  fruit_array_type    fruit; | ||||
|  | ||||
|     // test i-- | ||||
|     while (ie != i) { | ||||
|       ie--; | ||||
|       cout << *ie << " "; | ||||
|     } | ||||
|     cout << endl; | ||||
|     ie = array + sizeof(array)/sizeof(string); | ||||
| };  // test_opr_base | ||||
|  | ||||
|     // test i->m | ||||
|     while (i != ie) { | ||||
|       cout << i->size() << " "; | ||||
|       ++i; | ||||
|     } | ||||
|     cout << endl; | ||||
|     i = array; | ||||
| #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION | ||||
| //  A definition is required even for integral static constants | ||||
| const std::size_t test_opr_base::fruit_length; | ||||
| #endif | ||||
|  | ||||
|     // test i + n | ||||
|     while (i < ie) { | ||||
|       cout << *i << " "; | ||||
|       i = i + 2; | ||||
|     } | ||||
|     cout << endl; | ||||
|     i = array; | ||||
| template <typename T, typename R = T&, typename P = T*> | ||||
| class test_opr | ||||
|     : public test_opr_base | ||||
| { | ||||
|     typedef test_opr<T, R, P>  self_type; | ||||
|  | ||||
|     // test n + i | ||||
|     while (i < ie) { | ||||
|       cout << *i << " "; | ||||
|       i = ptrdiff_t(2) + i; | ||||
|     } | ||||
|     cout << endl; | ||||
|     i = array; | ||||
| public: | ||||
|     // Types | ||||
|     typedef T  value_type; | ||||
|     typedef R  reference; | ||||
|     typedef P  pointer; | ||||
|  | ||||
|     // test i - n | ||||
|     while (ie > i) { | ||||
|       ie = ie - 2; | ||||
|       cout << *ie << " "; | ||||
|     } | ||||
|     cout << endl; | ||||
|     ie = array + sizeof(array)/sizeof(string); | ||||
|     typedef test_iter<T, R, P>  iter_type; | ||||
|  | ||||
|     // test i[n] | ||||
|     for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j) | ||||
|       cout << i[j] << " "; | ||||
|     cout << endl; | ||||
|   } | ||||
|   { | ||||
|     test_iter<string, const string&, const string*> i = array,  | ||||
|       ie = array + sizeof(array)/sizeof(string); | ||||
|     // Test controller | ||||
|     static  void  master_test( char const name[] ); | ||||
|  | ||||
|     // Tests for all of the operators added by random_access_iterator_helper | ||||
| private: | ||||
|     // Test data | ||||
|     static iter_type const  fruit_begin; | ||||
|     static iter_type const  fruit_end; | ||||
|  | ||||
|     // test i++ | ||||
|     while (i != ie) | ||||
|       cout << *i++ << " "; | ||||
|     cout << endl; | ||||
|     i = array; | ||||
|     // Test parts | ||||
|     static  void  post_increment_test(); | ||||
|     static  void  post_decrement_test(); | ||||
|     static  void  indirect_referral_test(); | ||||
|     static  void  offset_addition_test(); | ||||
|     static  void  reverse_offset_addition_test(); | ||||
|     static  void  offset_subtraction_test(); | ||||
|     static  void  comparison_test(); | ||||
|     static  void  indexing_test(); | ||||
|  | ||||
|     // test i-- | ||||
|     while (ie != i) { | ||||
|       ie--; | ||||
|       cout << *ie << " "; | ||||
|     } | ||||
|     cout << endl; | ||||
|     ie = array + sizeof(array)/sizeof(string); | ||||
| };  // test_opr | ||||
|  | ||||
|     // test i->m | ||||
|     while (i != ie) { | ||||
|       cout << i->size() << " "; | ||||
|       ++i; | ||||
|     } | ||||
|     cout << endl; | ||||
|     i = array; | ||||
|  | ||||
|     // test i + n | ||||
|     while (i < ie) { | ||||
|       cout << *i << " "; | ||||
|       i = i + 2; | ||||
|     } | ||||
|     cout << endl; | ||||
|     i = array; | ||||
| // Class-static data definitions | ||||
| test_opr_base::fruit_array_type | ||||
|  test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" }; | ||||
|  | ||||
|     // test n + i | ||||
|     while (i < ie) { | ||||
|       cout << *i << " "; | ||||
|       i = ptrdiff_t(2) + i; | ||||
|     } | ||||
|     cout << endl; | ||||
|     i = array; | ||||
| template <typename T, typename R, typename P> | ||||
|   typename test_opr<T, R, P>::iter_type const | ||||
|  test_opr<T, R, P>::fruit_begin = test_iter<T,R,P>( fruit ); | ||||
|  | ||||
|     // test i - n | ||||
|     while (ie > i) { | ||||
|       ie = ie - 2; | ||||
|       cout << *ie << " "; | ||||
|     } | ||||
|     cout << endl; | ||||
|     ie = array + sizeof(array)/sizeof(string); | ||||
| template <typename T, typename R, typename P> | ||||
| typename test_opr<T, R, P>::iter_type const | ||||
|  test_opr<T, R, P>::fruit_end = test_iter<T,R,P>( fruit + fruit_length ); | ||||
|  | ||||
|     // test i[n] | ||||
|     for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j) | ||||
|       cout << i[j] << " "; | ||||
|     cout << endl; | ||||
|   } | ||||
|   return 0; | ||||
|  | ||||
| // Main testing function | ||||
| int | ||||
| test_main( int , char * [] ) | ||||
| { | ||||
|     using std::string; | ||||
|  | ||||
|     typedef test_opr<string, string &, string *>              test1_type; | ||||
|     typedef test_opr<string, string const &, string const *>  test2_type; | ||||
|  | ||||
|     test1_type::master_test( "non-const string" ); | ||||
|     test2_type::master_test( "const string" ); | ||||
|  | ||||
|     return boost::exit_success; | ||||
| } | ||||
|  | ||||
| // Tests for all of the operators added by random_access_iterator_helper | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::master_test | ||||
| ( | ||||
|     char const  name[] | ||||
| ) | ||||
| { | ||||
|     std::cout << "Doing test run for " << name << '.' << std::endl; | ||||
|  | ||||
|     post_increment_test(); | ||||
|     post_decrement_test(); | ||||
|     indirect_referral_test(); | ||||
|     offset_addition_test(); | ||||
|     reverse_offset_addition_test(); | ||||
|     offset_subtraction_test(); | ||||
|     comparison_test(); | ||||
|     indexing_test(); | ||||
| } | ||||
|  | ||||
| // Test post-increment | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::post_increment_test | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     std::cout << "\tDoing post-increment test." << std::endl; | ||||
|  | ||||
|     std::stringstream oss; | ||||
|     for ( iter_type i = fruit_begin ; i != fruit_end ; ) | ||||
|     { | ||||
|         oss << *i++ << ' '; | ||||
|     } | ||||
|  | ||||
|     BOOST_CHECK( oss.str() == "apple orange pear peach grape plum "); | ||||
| } | ||||
|  | ||||
| // Test post-decrement | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::post_decrement_test | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     std::cout << "\tDoing post-decrement test." << std::endl; | ||||
|  | ||||
|     std::stringstream oss; | ||||
|     for ( iter_type i = fruit_end ; i != fruit_begin ; ) | ||||
|     { | ||||
|         i--; | ||||
|         oss << *i << ' '; | ||||
|     } | ||||
|  | ||||
|     BOOST_CHECK( oss.str() == "plum grape peach pear orange apple "); | ||||
| } | ||||
|  | ||||
| // Test indirect structure referral | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::indirect_referral_test | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     std::cout << "\tDoing indirect reference test." << std::endl; | ||||
|  | ||||
|     std::stringstream oss; | ||||
|     for ( iter_type i = fruit_begin ; i != fruit_end ; ++i ) | ||||
|     { | ||||
|         oss << i->size() << ' '; | ||||
|     } | ||||
|  | ||||
|     BOOST_CHECK( oss.str() == "5 6 4 5 5 4 "); | ||||
| } | ||||
|  | ||||
| // Test offset addition | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::offset_addition_test | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     std::cout << "\tDoing offset addition test." << std::endl; | ||||
|  | ||||
|     std::ptrdiff_t const  two = 2; | ||||
|     std::stringstream oss; | ||||
|     for ( iter_type i = fruit_begin ; i != fruit_end ; i = i + two ) | ||||
|     { | ||||
|         oss << *i << ' '; | ||||
|     } | ||||
|  | ||||
|     BOOST_CHECK( oss.str() == "apple pear grape "); | ||||
| } | ||||
|  | ||||
| // Test offset addition, in reverse order | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::reverse_offset_addition_test | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     std::cout << "\tDoing reverse offset addition test." << std::endl; | ||||
|  | ||||
|     std::ptrdiff_t const  two = 2; | ||||
|     std::stringstream oss; | ||||
|     for ( iter_type i = fruit_begin ; i != fruit_end ; i = two + i ) | ||||
|     { | ||||
|         oss << *i << ' '; | ||||
|     } | ||||
|  | ||||
|     BOOST_CHECK( oss.str() == "apple pear grape "); | ||||
| } | ||||
|  | ||||
| // Test offset subtraction | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::offset_subtraction_test | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     std::cout << "\tDoing offset subtraction test." << std::endl; | ||||
|  | ||||
|     std::ptrdiff_t const  two = 2; | ||||
|     std::stringstream oss; | ||||
|     for ( iter_type i = fruit_end ; fruit_begin < i ; ) | ||||
|     { | ||||
|         i = i - two; | ||||
|         if ( (fruit_begin < i) || (fruit_begin == i) ) | ||||
|         { | ||||
|             oss << *i << ' '; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     BOOST_CHECK( oss.str() == "grape pear apple "); | ||||
| } | ||||
|  | ||||
| // Test comparisons | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::comparison_test | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     using std::cout; | ||||
|     using std::ptrdiff_t; | ||||
|  | ||||
|     cout << "\tDoing comparison tests.\n\t\tPass:"; | ||||
|  | ||||
|     for ( iter_type i = fruit_begin ; i != fruit_end ; ++i ) | ||||
|     { | ||||
|         ptrdiff_t const  i_offset = i - fruit_begin; | ||||
|  | ||||
|         cout << ' ' << *i << std::flush; | ||||
|         for ( iter_type j = fruit_begin ; j != fruit_end ; ++j ) | ||||
|         { | ||||
|             ptrdiff_t const  j_offset = j - fruit_begin; | ||||
|  | ||||
|             BOOST_CHECK( (i != j) == (i_offset != j_offset) ); | ||||
|             BOOST_CHECK( (i > j) == (i_offset > j_offset) ); | ||||
|             BOOST_CHECK( (i <= j) == (i_offset <= j_offset) ); | ||||
|             BOOST_CHECK( (i >= j) == (i_offset >= j_offset) ); | ||||
|         } | ||||
|     } | ||||
|     cout << std::endl; | ||||
| } | ||||
|  | ||||
| // Test indexing | ||||
| template <typename T, typename R, typename P> | ||||
| void | ||||
| test_opr<T, R, P>::indexing_test | ||||
| ( | ||||
| ) | ||||
| { | ||||
|     std::cout << "\tDoing indexing test." << std::endl; | ||||
|  | ||||
|     std::stringstream oss; | ||||
|     for ( std::size_t k = 0u ; k < fruit_length ; ++k ) | ||||
|     { | ||||
|         oss << fruit_begin[ k ] << ' '; | ||||
|     } | ||||
|  | ||||
|     BOOST_CHECK( oss.str() == "apple orange pear peach grape plum "); | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,8 @@ | ||||
| //  boost class noncopyable test program  ------------------------------------// | ||||
|  | ||||
| //  (C) Copyright boost.org 1999. 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. | ||||
| //  (C) Copyright Beman Dawes 1999. Distributed under the Boost | ||||
| //  Software License, Version 1.0. (See accompanying file | ||||
| //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org for most recent version including documentation. | ||||
|  | ||||
| @@ -12,7 +10,7 @@ | ||||
| //   9 Jun 99  Add unnamed namespace | ||||
| //   2 Jun 99  Initial Version | ||||
|  | ||||
| #include <boost/utility.hpp> | ||||
| #include <boost/noncopyable.hpp> | ||||
| #include <iostream> | ||||
|  | ||||
| //  This program demonstrates compiler errors resulting from trying to copy | ||||
| @@ -20,7 +18,7 @@ | ||||
|  | ||||
| namespace | ||||
| { | ||||
|     class DontTreadOnMe : boost::noncopyable | ||||
|     class DontTreadOnMe : private boost::noncopyable | ||||
|     { | ||||
|     public: | ||||
|          DontTreadOnMe() { std::cout << "defanged!" << std::endl; } | ||||
| @@ -35,4 +33,4 @@ int main() | ||||
|     object1 = object2; | ||||
|     return 0; | ||||
| }   // main | ||||
|    | ||||
|    | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| //  (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. | ||||
| //  (C) Copyright David Abrahams 2001. | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org for most recent version including documentation. | ||||
|  | ||||
| //  Revision History | ||||
| //  1  Apr 2001 Fixes for ICL; use BOOST_STATIC_CONSTANT | ||||
| //  11 Feb 2001 Fixes for Borland (David Abrahams) | ||||
| //  23 Jan 2001 Added test for wchar_t (David Abrahams) | ||||
| //  23 Jan 2001 Now statically selecting a test for signed numbers to avoid | ||||
| @@ -30,13 +30,6 @@ | ||||
| # include <limits> | ||||
| #endif | ||||
|  | ||||
| // A macro for declaring class compile-time constants. | ||||
| #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION | ||||
| # define DECLARE_CLASS_CONST(type, init) static const type init | ||||
| #else | ||||
| # define DECLARE_CLASS_CONST(type, init) enum { init } | ||||
| #endif | ||||
|  | ||||
| // ================================================================================= | ||||
| // template class complement_traits<Number> -- | ||||
| // | ||||
| @@ -53,8 +46,8 @@ template <unsigned size> struct complement; // forward | ||||
| template <class Number, unsigned size> | ||||
| struct complement_traits_aux | ||||
| { | ||||
|     DECLARE_CLASS_CONST(Number, max = complement<size>::template traits<Number>::max); | ||||
|     DECLARE_CLASS_CONST(Number, min = complement<size>::template traits<Number>::min); | ||||
|     BOOST_STATIC_CONSTANT(Number, max = complement<size>::template traits<Number>::max); | ||||
|     BOOST_STATIC_CONSTANT(Number, min = complement<size>::template traits<Number>::min); | ||||
| }; | ||||
|  | ||||
| template <unsigned size> | ||||
| @@ -64,14 +57,22 @@ struct complement | ||||
|     struct traits | ||||
|     { | ||||
|      private: | ||||
|         // indirection through complement_traits_aux neccessary to keep MSVC happy | ||||
|         // indirection through complement_traits_aux necessary to keep MSVC happy | ||||
|         typedef complement_traits_aux<Number, size - 1> prev; | ||||
|      public: | ||||
|         DECLARE_CLASS_CONST(Number, max = | ||||
| #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 | ||||
|       // GCC 4.0.2 ICEs on these C-style casts | ||||
|         BOOST_STATIC_CONSTANT(Number, max = | ||||
|                             Number((prev::max) << CHAR_BIT) | ||||
|                             + Number(UCHAR_MAX)); | ||||
|         BOOST_STATIC_CONSTANT(Number, min = Number((prev::min) << CHAR_BIT)); | ||||
| #else | ||||
|         BOOST_STATIC_CONSTANT(Number, max = | ||||
|                             Number(Number(prev::max) << CHAR_BIT) | ||||
|                             + Number(UCHAR_MAX)); | ||||
|          | ||||
|         DECLARE_CLASS_CONST(Number, min = Number(Number(prev::min) << CHAR_BIT)); | ||||
|         BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) << CHAR_BIT)); | ||||
| #endif | ||||
|     | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| @@ -85,8 +86,8 @@ template <> struct complement_base<false> | ||||
|     template <class Number> | ||||
|     struct values | ||||
|     { | ||||
|         DECLARE_CLASS_CONST(Number, min = 0); | ||||
|         DECLARE_CLASS_CONST(Number, max = UCHAR_MAX); | ||||
|         BOOST_STATIC_CONSTANT(Number, min = 0); | ||||
|         BOOST_STATIC_CONSTANT(Number, max = UCHAR_MAX); | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| @@ -95,8 +96,8 @@ template <> struct complement_base<true> | ||||
|     template <class Number> | ||||
|     struct values | ||||
|     { | ||||
|         DECLARE_CLASS_CONST(Number, min = SCHAR_MIN); | ||||
|         DECLARE_CLASS_CONST(Number, max = SCHAR_MAX); | ||||
|         BOOST_STATIC_CONSTANT(Number, min = SCHAR_MIN); | ||||
|         BOOST_STATIC_CONSTANT(Number, max = SCHAR_MAX); | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| @@ -107,10 +108,10 @@ struct complement<1> | ||||
|     template <class Number> | ||||
|     struct traits | ||||
|     { | ||||
|         DECLARE_CLASS_CONST(bool, is_signed = boost::detail::is_signed<Number>::value); | ||||
|         DECLARE_CLASS_CONST(Number, min = | ||||
|         BOOST_STATIC_CONSTANT(bool, is_signed = boost::detail::is_signed<Number>::value); | ||||
|         BOOST_STATIC_CONSTANT(Number, min = | ||||
|                             complement_base<is_signed>::template values<Number>::min); | ||||
|         DECLARE_CLASS_CONST(Number, max = | ||||
|         BOOST_STATIC_CONSTANT(Number, max = | ||||
|                             complement_base<is_signed>::template values<Number>::max); | ||||
|     }; | ||||
| }; | ||||
| @@ -121,8 +122,8 @@ struct complement<1> | ||||
| template <class Number> | ||||
| struct complement_traits | ||||
| { | ||||
|     DECLARE_CLASS_CONST(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max)); | ||||
|     DECLARE_CLASS_CONST(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min)); | ||||
|     BOOST_STATIC_CONSTANT(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max)); | ||||
|     BOOST_STATIC_CONSTANT(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min)); | ||||
| }; | ||||
|  | ||||
| // ================================================================================= | ||||
| @@ -151,9 +152,9 @@ template <> struct stream_as<signed char>  { | ||||
|     typedef unsigned char t1; typedef unsigned t2; | ||||
| }; | ||||
|  | ||||
| #if defined(BOOST_MSVC) // No intmax streaming built-in | ||||
| #if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in | ||||
|  | ||||
| // On this platform, __int64 and __uint64 get streamed as strings | ||||
| // With this library implementation, __int64 and __uint64 get streamed as strings | ||||
| template <> struct stream_as<boost::uintmax_t> { | ||||
|     typedef std::string t1; | ||||
|     typedef std::string t2; | ||||
| @@ -174,7 +175,7 @@ template <class T> struct promote | ||||
|     } | ||||
| }; | ||||
|  | ||||
| #if defined(BOOST_MSVC) // No intmax streaming built-in | ||||
| #if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in | ||||
|  | ||||
| // On this platform, stream them as long/unsigned long if they fit. | ||||
| // Otherwise, write a string. | ||||
| @@ -220,7 +221,7 @@ struct signed_tag {}; | ||||
| // Tests for unsigned numbers. The extra default Number parameter works around | ||||
| // an MSVC bug. | ||||
| template <class Number> | ||||
| void test_aux(unsigned_tag, Number* = 0) | ||||
| void test_aux(unsigned_tag, Number*) | ||||
| { | ||||
|     typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type; | ||||
|     BOOST_STATIC_ASSERT(!boost::detail::is_signed<Number>::value); | ||||
| @@ -228,10 +229,16 @@ void test_aux(unsigned_tag, Number* = 0) | ||||
|         (sizeof(Number) < sizeof(boost::intmax_t)) | ||||
|         | (boost::is_same<difference_type, boost::intmax_t>::value)); | ||||
|  | ||||
| #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 | ||||
|     // GCC 4.0.2 ICEs on this C-style cases | ||||
|     BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0)); | ||||
|     BOOST_STATIC_ASSERT((complement_traits<Number>::min) == Number(0)); | ||||
| #else | ||||
|     // Force casting to Number here to work around the fact that it's an enum on MSVC | ||||
|     BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0)); | ||||
|     BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) == Number(0)); | ||||
|      | ||||
| #endif | ||||
|  | ||||
|     const Number max = complement_traits<Number>::max; | ||||
|     const Number min = complement_traits<Number>::min; | ||||
|      | ||||
| @@ -262,7 +269,7 @@ struct in_range_tag {}; | ||||
| // This test morsel gets executed for numbers whose difference will always be | ||||
| // representable in intmax_t | ||||
| template <class Number> | ||||
| void signed_test(in_range_tag, Number* = 0) | ||||
| void signed_test(in_range_tag, Number*) | ||||
| { | ||||
|     BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value); | ||||
|     typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type; | ||||
| @@ -283,7 +290,7 @@ void signed_test(in_range_tag, Number* = 0) | ||||
| // This test morsel gets executed for numbers whose difference may exceed the | ||||
| // capacity of intmax_t. | ||||
| template <class Number> | ||||
| void signed_test(out_of_range_tag, Number* = 0) | ||||
| void signed_test(out_of_range_tag, Number*) | ||||
| { | ||||
|     BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value); | ||||
|     typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type; | ||||
| @@ -307,7 +314,7 @@ void signed_test(out_of_range_tag, Number* = 0) | ||||
| } | ||||
|  | ||||
| template <class Number> | ||||
| void test_aux(signed_tag, Number* = 0) | ||||
| void test_aux(signed_tag, Number*) | ||||
| { | ||||
|     typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type; | ||||
|     BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value); | ||||
| @@ -315,10 +322,15 @@ void test_aux(signed_tag, Number* = 0) | ||||
|         (sizeof(Number) < sizeof(boost::intmax_t)) | ||||
|         | (boost::is_same<difference_type, Number>::value)); | ||||
|  | ||||
| #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 | ||||
|     // GCC 4.0.2 ICEs on this cast | ||||
|     BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0)); | ||||
|     BOOST_STATIC_ASSERT((complement_traits<Number>::min) < Number(0)); | ||||
| #else | ||||
|     // Force casting to Number here to work around the fact that it's an enum on MSVC | ||||
|     BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0)); | ||||
|     BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) < Number(0)); | ||||
|      | ||||
| #endif     | ||||
|     const Number max = complement_traits<Number>::max; | ||||
|     const Number min = complement_traits<Number>::min; | ||||
|      | ||||
| @@ -334,7 +346,7 @@ void test_aux(signed_tag, Number* = 0) | ||||
|                           out_of_range_tag | ||||
|                         >::type | ||||
|         range_tag; | ||||
|     signed_test<Number>(range_tag()); | ||||
|     signed_test<Number>(range_tag(), 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -353,7 +365,7 @@ void test(Number* = 0) | ||||
|  | ||||
|     // factoring out difference_type for the assert below confused Borland :( | ||||
|     typedef boost::detail::is_signed< | ||||
| #ifndef BOOST_MSVC | ||||
| #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 | ||||
|         typename | ||||
| #endif | ||||
|         boost::detail::numeric_traits<Number>::difference_type | ||||
| @@ -364,7 +376,7 @@ void test(Number* = 0) | ||||
|         boost::detail::is_signed<Number>::value | ||||
|         >::template then<signed_tag, unsigned_tag>::type signedness; | ||||
|      | ||||
|     test_aux<Number>(signedness()); | ||||
|     test_aux<Number>(signedness(), 0); | ||||
|     std::cout << "passed" << std::endl; | ||||
| } | ||||
|  | ||||
| @@ -380,9 +392,9 @@ int main() | ||||
|     test<unsigned int>(); | ||||
|     test<long>(); | ||||
|     test<unsigned long>(); | ||||
| #if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) | ||||
|     test<long long>(); | ||||
|     test<unsigned long long>(); | ||||
| #if defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_INTEGRAL_INT64_T) | ||||
|     test< ::boost::long_long_type>(); | ||||
|     test< ::boost::ulong_long_type>(); | ||||
| #elif defined(BOOST_MSVC) | ||||
|     // The problem of not having compile-time static class constants other than | ||||
|     // enums prevents this from working, since values get truncated. | ||||
|   | ||||
							
								
								
									
										2570
									
								
								operators.htm
									
									
									
									
									
								
							
							
						
						
									
										2570
									
								
								operators.htm
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,391 +0,0 @@ | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
| <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> | ||||
| <meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
| <title>Projection Iterator Adaptor Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|  | ||||
| <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" | ||||
| align="center" width="277" height="86"> | ||||
|  | ||||
| <h1>Projection Iterator Adaptor</h1> | ||||
|  | ||||
| Defined in header | ||||
| <a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a> | ||||
|  | ||||
| <p> | ||||
| The projection iterator adaptor is similar to the <a | ||||
| href="./transform_iterator.htm">transform iterator adaptor</a> in that | ||||
| its <tt>operator*()</tt> applies some function to the result of | ||||
| dereferencing the base iterator and then returns the result. The | ||||
| difference is that the function must return a reference to some | ||||
| existing object (for example, a data member within the | ||||
| <tt>value_type</tt> of the base iterator). The following | ||||
| <b>pseudo-code</b> gives the basic idea. The data member <tt>p</tt> is | ||||
| the function object. | ||||
|  | ||||
| <pre> | ||||
|   reference projection_iterator::operator*() const { | ||||
|     return this->p(*this->base_iterator); | ||||
|   } | ||||
| </pre> | ||||
|  | ||||
| <h2>Synopsis</h2> | ||||
|  | ||||
| <pre> | ||||
| namespace boost { | ||||
|   template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator> | ||||
|   struct projection_iterator_generator; | ||||
|    | ||||
|   template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>,  | ||||
|             class BaseIterator, class ConstBaseIterator> | ||||
|   struct projection_iterator_pair_generator; | ||||
|  | ||||
|   template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator> | ||||
|   typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type | ||||
|   make_projection_iterator(BaseIterator base, | ||||
| 			   const AdaptableUnaryFunction& p = AdaptableUnaryFunction()) | ||||
|  | ||||
|   template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class ConstBaseIterator> | ||||
|   typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type | ||||
|   make_const_projection_iterator(ConstBaseIterator base, | ||||
|                                  const AdaptableUnaryFunction& p = AdaptableUnaryFunction())   | ||||
| } | ||||
| </pre> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <h2><a name="projection_iterator_generator">The Projection Iterator Type | ||||
| Generator</a></h2> | ||||
|  | ||||
| The class <tt>projection_iterator_generator</tt> is a helper class | ||||
| whose purpose is to construct an projection iterator type.  The main | ||||
| template parameter for this class is the <a | ||||
| href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a> | ||||
| function object type and the <tt>BaseIterator</tt> type that is being | ||||
| wrapped. | ||||
|  | ||||
| <pre> | ||||
| template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator> | ||||
| class projection_iterator_generator | ||||
| { | ||||
| public: | ||||
|   typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting projection iterator type  | ||||
| }; | ||||
| </pre> | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| In the following example we have a list of personnel records. Each | ||||
| record has an employee's name and ID number. We want to be able to | ||||
| traverse through the list accessing either the name or the ID numbers | ||||
| of the employees using the projection iterator so we create the | ||||
| function object classes <tt>select_name</tt> and | ||||
| <tt>select_ID</tt>. We then use the | ||||
| <tt>projection_iterator_generator</tt> class to create a projection | ||||
| iterator and use it to print out the names of the employees. | ||||
|  | ||||
| <pre> | ||||
| #include <boost/config.hpp> | ||||
| #include <list> | ||||
| #include <iostream> | ||||
| #include <iterator> | ||||
| #include <algorithm> | ||||
| #include <string> | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
|  | ||||
| struct personnel_record { | ||||
|   personnel_record(std::string n, int id) : m_name(n), m_ID(id) { } | ||||
|   std::string m_name; | ||||
|   int m_ID; | ||||
| }; | ||||
|  | ||||
| struct select_name { | ||||
|   typedef personnel_record argument_type; | ||||
|   typedef std::string result_type; | ||||
|   const std::string& operator()(const personnel_record& r) const { | ||||
|     return r.m_name; | ||||
|   } | ||||
|   std::string& operator()(personnel_record& r) const { | ||||
|     return r.m_name; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| struct select_ID { | ||||
|   typedef personnel_record argument_type; | ||||
|   typedef int result_type; | ||||
|   const int& operator()(const personnel_record& r) const { | ||||
|     return r.m_ID; | ||||
|   } | ||||
|   int& operator()(personnel_record& r) const { | ||||
|     return r.m_ID; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   std::list<personnel_record> personnel_list; | ||||
|  | ||||
|   personnel_list.push_back(personnel_record("Barney", 13423)); | ||||
|   personnel_list.push_back(personnel_record("Fred", 12343)); | ||||
|   personnel_list.push_back(personnel_record("Wilma", 62454)); | ||||
|   personnel_list.push_back(personnel_record("Betty", 20490)); | ||||
|  | ||||
|   // Example of using projection_iterator_generator | ||||
|   // to print out the names in the personnel list. | ||||
|  | ||||
|   boost::projection_iterator_generator<select_name, | ||||
|     std::list<personnel_record>::iterator>::type | ||||
|     personnel_first(personnel_list.begin()), | ||||
|     personnel_last(personnel_list.end()); | ||||
|  | ||||
|   std::copy(personnel_first, personnel_last, | ||||
|             std::ostream_iterator<std::string>(std::cout, "\n")); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // to be continued... | ||||
| </pre> | ||||
| The output for this part is: | ||||
| <pre> | ||||
| Barney | ||||
| Fred | ||||
| Wilma | ||||
| Betty | ||||
| </pre> | ||||
|  | ||||
| <h3>Template Parameters</h3> | ||||
|  | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH>Parameter</TH><TH>Description</TH> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD> | ||||
| <TD>The type of the function object. The <tt>argument_type</tt> of the | ||||
| function must match the value type of the base iterator. The function | ||||
| should return a reference to the function's <tt>result_type</tt>. | ||||
| The <tt>result_type</tt> will be the resulting iterator's <tt>value_type</tt>. | ||||
| </TD> | ||||
| </TD> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>BaseIterator</tt></TD> | ||||
| <TD>The iterator type being wrapped.</TD> | ||||
| </TD> | ||||
| </TR> | ||||
|  | ||||
| </Table> | ||||
|  | ||||
| <h3>Model of</h3> | ||||
|  | ||||
| If the base iterator is a model of <a | ||||
| href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
| Access Iterator</a> then so is the resulting projection iterator.  If | ||||
| the base iterator supports less functionality than this the resulting | ||||
| projection iterator will also support less functionality. | ||||
|  | ||||
| <h3>Members</h3> | ||||
|  | ||||
| The projection iterator type implements the member functions and | ||||
| operators required of the <a | ||||
| href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
| Access Iterator</a> concept. | ||||
| In addition it has the following constructor: | ||||
|  | ||||
| <pre> | ||||
| projection_iterator_generator::type(const BaseIterator& it, | ||||
|                                     const AdaptableUnaryFunction& p = AdaptableUnaryFunction()) | ||||
| </pre> | ||||
|  | ||||
| <p> | ||||
| <hr> | ||||
| <p> | ||||
|  | ||||
| <h2><a name="projection_iterator_pair_generator">The Projection Iterator Pair | ||||
| Generator</a></h2> | ||||
|  | ||||
| Sometimes a mutable/const pair of iterator types is needed, such as | ||||
| when implementing a container type. The | ||||
| <tt>projection_iterator_pair_generator</tt> class makes it more | ||||
| convenient to create this pair of iterator types. | ||||
|  | ||||
| <pre> | ||||
| template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator, class ConstBaseIterator> | ||||
| class projection_iterator_pair_generator | ||||
| { | ||||
| public: | ||||
|   typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> iterator;       // the mutable projection iterator type  | ||||
|   typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> const_iterator; // the immutable projection iterator type  | ||||
| }; | ||||
| </pre> | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| In this part of the example we use the | ||||
| <tt>projection_iterator_pair_generator</tt> to create a mutable/const | ||||
| pair of projection iterators that access the ID numbers of the | ||||
| personnel. We use the mutable iterator to re-index the ID numbers from | ||||
| zero. We then use the constant iterator to print the ID numbers out. | ||||
|  | ||||
| <pre> | ||||
|   // continuing from the last example... | ||||
|  | ||||
|   typedef boost::projection_iterator_pair_generator<select_ID, | ||||
|     std::list<personnel_record>::iterator, | ||||
|     std::list<personnel_record>::const_iterator> PairGen; | ||||
|  | ||||
|   PairGen::iterator ID_first(personnel_list.begin()), | ||||
|     ID_last(personnel_list.end()); | ||||
|  | ||||
|   int new_id = 0; | ||||
|   while (ID_first != ID_last) { | ||||
|     *ID_first = new_id++; | ||||
|     ++ID_first; | ||||
|   } | ||||
|  | ||||
|   PairGen::const_iterator const_ID_first(personnel_list.begin()), | ||||
|     const_ID_last(personnel_list.end()); | ||||
|  | ||||
|   std::copy(const_ID_first, const_ID_last, | ||||
|             std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|   std::cout << std::endl; | ||||
|    | ||||
|   // to be continued... | ||||
| </pre> | ||||
| The output is: | ||||
| <pre> | ||||
| 0 1 2 3  | ||||
| </pre> | ||||
|  | ||||
| <h3>Template Parameters</h3> | ||||
|  | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH>Parameter</TH><TH>Description</TH> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD> | ||||
| <TD>The type of the function object. The <tt>argument_type</tt> of the | ||||
| function must match the value type of the base iterator. The function | ||||
| should return a true reference to the function's <tt>result_type</tt>. | ||||
| The <tt>result_type</tt> will be the resulting iterator's <tt>value_type</tt>. | ||||
| </TD> | ||||
| </TD> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>BaseIterator</tt></TD> | ||||
| <TD>The mutable iterator type being wrapped.</TD> | ||||
| </TD> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><tt>ConstBaseIterator</tt></TD> | ||||
| <TD>The constant iterator type being wrapped.</TD> | ||||
| </TD> | ||||
| </TR> | ||||
|  | ||||
| </Table> | ||||
|  | ||||
| <h3>Model of</h3> | ||||
|  | ||||
| If the base iterator types model the <a | ||||
| href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
| Access Iterator</a> then so do the resulting projection iterator | ||||
| types.  If the base iterators support less functionality the | ||||
| resulting projection iterator types will also support less | ||||
| functionality.  The resulting <tt>iterator</tt> type is mutable, and | ||||
| the resulting <tt>const_iterator</tt> type is constant. | ||||
|  | ||||
| <h3>Members</h3> | ||||
|  | ||||
| The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types | ||||
| implements the member functions and operators required of the <a | ||||
| href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random | ||||
| Access Iterator</a> concept.  In addition they support the following | ||||
| constructors: | ||||
|  | ||||
| <pre> | ||||
| projection_iterator_pair_generator::iterator(const BaseIterator& it, | ||||
|                                              const AdaptableUnaryFunction& p = AdaptableUnaryFunction())</pre> | ||||
|  | ||||
| <pre> | ||||
| projection_iterator_pair_generator::const_iterator(const BaseIterator& it, | ||||
|                                                    const AdaptableUnaryFunction& p = AdaptableUnaryFunction()) | ||||
| </pre> | ||||
|  | ||||
| <p> | ||||
| <hr> | ||||
| <p> | ||||
|  | ||||
| <h2><a name="make_projection_iterator">The Projection Iterator Object Generators</a></h2> | ||||
|  | ||||
| The <tt>make_projection_iterator()</tt> and | ||||
| <tt>make_const_projection_iterator()</tt> functions provide a more | ||||
| convenient way to create projection iterator objects. The functions | ||||
| save the user the trouble of explicitly writing out the iterator | ||||
| types. | ||||
|  | ||||
| <pre> | ||||
| template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator> | ||||
| typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type | ||||
| make_projection_iterator(BaseIterator base, | ||||
| 			 const AdaptableUnaryFunction& p = AdaptableUnaryFunction())   | ||||
|  | ||||
| template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class ConstBaseIterator> | ||||
| typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type | ||||
| make_const_projection_iterator(ConstBaseIterator base, | ||||
| 			       const AdaptableUnaryFunction& p = AdaptableUnaryFunction())   | ||||
| </pre> | ||||
|  | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| In this part of the example, we again print out the names of the | ||||
| personnel, but this time we use the | ||||
| <tt>make_const_projection_iterator()</tt> function to save some typing. | ||||
|  | ||||
| <pre> | ||||
|   // continuing from the last example... | ||||
|  | ||||
|   std::copy | ||||
|     (boost::make_const_projection_iterator<select_name>(personnel_list.begin()), | ||||
|      boost::make_const_projection_iterator<select_name>(personnel_list.end()), | ||||
|      std::ostream_iterator<std::string>(std::cout, "\n")); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| </pre> | ||||
| The output is: | ||||
| <pre> | ||||
| Barney | ||||
| Fred | ||||
| Wilma | ||||
| Betty | ||||
| </pre> | ||||
|  | ||||
| <hr> | ||||
| <p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" --></p> | ||||
| <p><EFBFBD> Copyright Jeremy Siek 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> | ||||
|  | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
| <!--  LocalWords:  html charset alt gif hpp BaseIterator const namespace struct | ||||
|  --> | ||||
| <!--  LocalWords:  ConstPointer ConstReference typename iostream int abcdefg | ||||
|  --> | ||||
| <!--  LocalWords:  sizeof  PairGen pre Siek htm AdaptableUnaryFunction | ||||
|  --> | ||||
| <!--  LocalWords:  ConstBaseIterator | ||||
|  --> | ||||
| @@ -1,96 +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 <list> | ||||
| #include <iostream> | ||||
| #include <iterator> | ||||
| #include <algorithm> | ||||
| #include <string> | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
|  | ||||
| struct personnel_record { | ||||
|   personnel_record(std::string n, int id) : m_name(n), m_ID(id) { } | ||||
|   std::string m_name; | ||||
|   int m_ID; | ||||
| }; | ||||
|  | ||||
| struct select_name { | ||||
|   typedef personnel_record argument_type; | ||||
|   typedef std::string result_type; | ||||
|   const std::string& operator()(const personnel_record& r) const { | ||||
|     return r.m_name; | ||||
|   } | ||||
|   std::string& operator()(personnel_record& r) const { | ||||
|     return r.m_name; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| struct select_ID { | ||||
|   typedef personnel_record argument_type; | ||||
|   typedef int result_type; | ||||
|   const int& operator()(const personnel_record& r) const { | ||||
|     return r.m_ID; | ||||
|   } | ||||
|   int& operator()(personnel_record& r) const { | ||||
|     return r.m_ID; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   std::list<personnel_record> personnel_list; | ||||
|  | ||||
|   personnel_list.push_back(personnel_record("Barney", 13423)); | ||||
|   personnel_list.push_back(personnel_record("Fred", 12343)); | ||||
|   personnel_list.push_back(personnel_record("Wilma", 62454)); | ||||
|   personnel_list.push_back(personnel_record("Betty", 20490)); | ||||
|  | ||||
|   // Example of using projection_iterator_generator | ||||
|   // to print out the names in the personnel list. | ||||
|  | ||||
|   boost::projection_iterator_generator<select_name, | ||||
|     std::list<personnel_record>::iterator>::type | ||||
|     personnel_first(personnel_list.begin()), | ||||
|     personnel_last(personnel_list.end()); | ||||
|  | ||||
|   std::copy(personnel_first, personnel_last, | ||||
|             std::ostream_iterator<std::string>(std::cout, "\n")); | ||||
|   std::cout << std::endl; | ||||
|    | ||||
|   // Example of using projection_iterator_pair_generator | ||||
|   // to assign new ID numbers to the personnel. | ||||
|    | ||||
|   typedef boost::projection_iterator_pair_generator<select_ID, | ||||
|     std::list<personnel_record>::iterator, | ||||
|     std::list<personnel_record>::const_iterator> PairGen; | ||||
|  | ||||
|   PairGen::iterator ID_first(personnel_list.begin()), | ||||
|     ID_last(personnel_list.end()); | ||||
|  | ||||
|   int new_id = 0; | ||||
|   while (ID_first != ID_last) { | ||||
|     *ID_first = new_id++; | ||||
|     ++ID_first; | ||||
|   } | ||||
|  | ||||
|   PairGen::const_iterator const_ID_first(personnel_list.begin()), | ||||
|     const_ID_last(personnel_list.end()); | ||||
|  | ||||
|   std::copy(const_ID_first, const_ID_last, | ||||
|             std::ostream_iterator<int>(std::cout, " ")); | ||||
|   std::cout << std::endl; | ||||
|   std::cout << std::endl; | ||||
|    | ||||
|   // Example of using make_const_projection_iterator() | ||||
|   // to print out the names in the personnel list again. | ||||
|    | ||||
|   std::copy | ||||
|     (boost::make_const_projection_iterator<select_name>(personnel_list.begin()), | ||||
|      boost::make_const_projection_iterator<select_name>(personnel_list.end()), | ||||
|      std::ostream_iterator<std::string>(std::cout, "\n")); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										134
									
								
								ref_ct_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								ref_ct_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| // Copyright David Abrahams and Aleksey Gurtovoy | ||||
| // 2002-2004. Distributed under the Boost Software License, Version | ||||
| // 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| // compile-time test for "boost/ref.hpp" header content | ||||
| // see 'ref_test.cpp' for run-time part | ||||
|  | ||||
| #include <boost/ref.hpp> | ||||
| #include <boost/type_traits/is_same.hpp> | ||||
| #include <boost/type_traits/remove_const.hpp> | ||||
| #include <boost/static_assert.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
|  | ||||
| #include <boost/mpl/assert.hpp> | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| template< typename T, typename U > | ||||
| void ref_test(boost::reference_wrapper<U>) | ||||
| { | ||||
|     typedef typename boost::reference_wrapper<U>::type type; | ||||
|     BOOST_STATIC_ASSERT((boost::is_same<U,type>::value)); | ||||
|     BOOST_STATIC_ASSERT((boost::is_same<T,type>::value)); | ||||
| } | ||||
|  | ||||
| template< typename T > | ||||
| void assignable_test(T x) | ||||
| { | ||||
|     x = x; | ||||
| } | ||||
|  | ||||
| template< bool R, typename T > | ||||
| void is_reference_wrapper_test(T) | ||||
| { | ||||
|     BOOST_STATIC_ASSERT(boost::is_reference_wrapper<T>::value == R); | ||||
| } | ||||
|  | ||||
| template< typename R, typename Ref > | ||||
| void cxx_reference_test(Ref) | ||||
| { | ||||
| #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) | ||||
|     typedef typename boost::remove_const<Ref>::type ref; | ||||
|     BOOST_STATIC_ASSERT((boost::is_same<R,ref>::value)); | ||||
| #else | ||||
|     BOOST_STATIC_ASSERT((boost::is_same<R,Ref>::value)); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| template< typename R, typename Ref > | ||||
| void unwrap_reference_test(Ref) | ||||
| { | ||||
| #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) | ||||
|     typedef typename boost::remove_const<Ref>::type ref; | ||||
|     typedef typename boost::unwrap_reference<ref>::type type; | ||||
| #else | ||||
|     typedef typename boost::unwrap_reference<Ref>::type type; | ||||
| #endif | ||||
|     BOOST_STATIC_ASSERT((boost::is_same<R,type>::value)); | ||||
| } | ||||
|  | ||||
| } // namespace | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     int i = 0; | ||||
|     int& ri = i; | ||||
|  | ||||
|     int const ci = 0; | ||||
|     int const& rci = ci; | ||||
|  | ||||
|     // 'ref/cref' functions test | ||||
|     ref_test<int>(boost::ref(i)); | ||||
|     ref_test<int>(boost::ref(ri)); | ||||
|     ref_test<int const>(boost::ref(ci)); | ||||
|     ref_test<int const>(boost::ref(rci)); | ||||
|  | ||||
|     ref_test<int const>(boost::cref(i)); | ||||
|     ref_test<int const>(boost::cref(ri)); | ||||
|     ref_test<int const>(boost::cref(ci)); | ||||
|     ref_test<int const>(boost::cref(rci)); | ||||
|  | ||||
|     // test 'assignable' requirement | ||||
|     assignable_test(boost::ref(i)); | ||||
|     assignable_test(boost::ref(ri)); | ||||
|     assignable_test(boost::cref(i)); | ||||
|     assignable_test(boost::cref(ci)); | ||||
|     assignable_test(boost::cref(rci)); | ||||
|  | ||||
|     // 'is_reference_wrapper' test | ||||
|     is_reference_wrapper_test<true>(boost::ref(i)); | ||||
|     is_reference_wrapper_test<true>(boost::ref(ri)); | ||||
|     is_reference_wrapper_test<true>(boost::cref(i)); | ||||
|     is_reference_wrapper_test<true>(boost::cref(ci)); | ||||
|     is_reference_wrapper_test<true>(boost::cref(rci)); | ||||
|  | ||||
|     is_reference_wrapper_test<false>(i); | ||||
|     is_reference_wrapper_test<false, int&>(ri); | ||||
|     is_reference_wrapper_test<false>(ci); | ||||
|     is_reference_wrapper_test<false, int const&>(rci); | ||||
|  | ||||
|     // ordinary references/function template arguments deduction test | ||||
|     cxx_reference_test<int>(i); | ||||
|     cxx_reference_test<int>(ri); | ||||
|     cxx_reference_test<int>(ci); | ||||
|     cxx_reference_test<int>(rci); | ||||
|  | ||||
|     cxx_reference_test<int&, int&>(i); | ||||
|     cxx_reference_test<int&, int&>(ri); | ||||
|     cxx_reference_test<int const&, int const&>(i); | ||||
|     cxx_reference_test<int const&, int const&>(ri); | ||||
|     cxx_reference_test<int const&, int const&>(ci); | ||||
|     cxx_reference_test<int const&, int const&>(rci); | ||||
|  | ||||
|     // 'unwrap_reference' test | ||||
|     unwrap_reference_test<int>(boost::ref(i)); | ||||
|     unwrap_reference_test<int>(boost::ref(ri)); | ||||
|     unwrap_reference_test<int const>(boost::cref(i)); | ||||
|     unwrap_reference_test<int const>(boost::cref(ci)); | ||||
|     unwrap_reference_test<int const>(boost::cref(rci)); | ||||
|  | ||||
|     unwrap_reference_test<int>(i); | ||||
|     unwrap_reference_test<int>(ri); | ||||
|     unwrap_reference_test<int>(ci); | ||||
|     unwrap_reference_test<int>(rci); | ||||
|     unwrap_reference_test<int&, int&>(i); | ||||
|     unwrap_reference_test<int&, int&>(ri); | ||||
|     unwrap_reference_test<int const&, int const&>(i); | ||||
|     unwrap_reference_test<int const&, int const&>(ri); | ||||
|     unwrap_reference_test<int const&, int const&>(ci); | ||||
|     unwrap_reference_test<int const&, int const&>(rci); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										78
									
								
								ref_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								ref_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| // Copyright David Abrahams and Aleksey Gurtovoy | ||||
| // 2002-2004. Distributed under the Boost Software License, Version | ||||
| // 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| // run-time test for "boost/ref.hpp" header content | ||||
| // see 'ref_ct_test.cpp' for compile-time part | ||||
|  | ||||
| #if defined(_MSC_VER) && !defined(__ICL) | ||||
| # pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| # pragma warning(disable: 4710)  // function not inlined | ||||
| # pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| # pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| #include <boost/ref.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | ||||
| # pragma warning(push, 3) | ||||
| #endif | ||||
|  | ||||
| #include <iostream> | ||||
|  | ||||
| #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | ||||
| # pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #define BOOST_INCLUDE_MAIN | ||||
| #include <boost/test/test_tools.hpp> | ||||
|  | ||||
| namespace { | ||||
| using namespace boost; | ||||
|  | ||||
| template <class T> | ||||
| struct ref_wrapper | ||||
| { | ||||
|     // Used to verify implicit conversion | ||||
|     static T* get_pointer(T& x) | ||||
|     { | ||||
|         return &x; | ||||
|     } | ||||
|  | ||||
|     static T const* get_const_pointer(T const& x) | ||||
|     { | ||||
|         return &x; | ||||
|     } | ||||
|  | ||||
|     template <class Arg> | ||||
|     static T* passthru(Arg x) | ||||
|     { | ||||
|         return get_pointer(x); | ||||
|     } | ||||
|  | ||||
|     template <class Arg> | ||||
|     static T const* cref_passthru(Arg x) | ||||
|     { | ||||
|         return get_const_pointer(x); | ||||
|     } | ||||
|  | ||||
|     static void test(T x) | ||||
|     { | ||||
|         BOOST_CHECK(passthru(ref(x)) == &x); | ||||
|         BOOST_CHECK(&ref(x).get() == &x); | ||||
|  | ||||
|         BOOST_CHECK(cref_passthru(cref(x)) == &x); | ||||
|         BOOST_CHECK(&cref(x).get() == &x); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace unnamed | ||||
|  | ||||
| int test_main(int, char * []) | ||||
| { | ||||
|     ref_wrapper<int>::test(1); | ||||
|     ref_wrapper<int const>::test(1); | ||||
|     return 0; | ||||
| } | ||||
| @@ -1,331 +0,0 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN"> | ||||
|  | ||||
| <html> | ||||
| <head> | ||||
|     <meta name="generator" content="HTML Tidy, see www.w3.org"> | ||||
|     <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
|     <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> | ||||
|     <meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
|  | ||||
|     <title>Reverse Iterator Adaptor Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|     <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align= | ||||
|     "center" width="277" height="86">  | ||||
|  | ||||
|     <h1>Reverse Iterator Adaptor</h1> | ||||
|     Defined in header <a href= | ||||
|     "../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>  | ||||
|  | ||||
|     <p>The reverse iterator adaptor flips the direction of a base iterator's | ||||
|     motion. Invoking <tt>operator++()</tt> moves the base iterator backward and | ||||
|     invoking <tt>operator--()</tt> moves the base iterator forward. The Boost | ||||
|     reverse iterator adaptor is better to use than the | ||||
|     <tt>std::reverse_iterator</tt> class in situations where pairs of | ||||
|     mutable/constant iterators are needed (e.g., in containers) because | ||||
|     comparisons and conversions between the mutable and const versions are | ||||
|     implemented correctly. | ||||
|  | ||||
|     <h2>Synopsis</h2> | ||||
| <pre> | ||||
| namespace boost { | ||||
|   template <class <a href= | ||||
| "http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>, | ||||
|             class Value, class Reference, class Pointer, class Category, class Distance> | ||||
|   struct reverse_iterator_generator; | ||||
|    | ||||
|   template <class <a href= | ||||
| "http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>> | ||||
|   typename reverse_iterator_generator<BidirectionalIterator>::type | ||||
|   make_reverse_iterator(BidirectionalIterator base)   | ||||
| } | ||||
| </pre> | ||||
|     <hr> | ||||
|  | ||||
|     <h2><a name="reverse_iterator_generator">The Reverse Iterator Type | ||||
|     Generator</a></h2> | ||||
|     The <tt>reverse_iterator_generator</tt> template is a <a href= | ||||
|     "../../more/generic_programming.html#type_generator">generator</a> of | ||||
|     reverse iterator types. The main template parameter for this class is the | ||||
|     base <tt>BidirectionalIterator</tt> type that is being adapted. In most | ||||
|     cases the associated types of the base iterator can be deduced using | ||||
|     <tt>std::iterator_traits</tt>, but in some situations the user may want to | ||||
|     override these types, so there are also template parameters for the base | ||||
|     iterator's associated types.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class <a href= | ||||
| "http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>, | ||||
|           class Value, class Reference, class Pointer, class Category, class Distance> | ||||
| class reverse_iterator_generator | ||||
| { | ||||
| public: | ||||
|   typedef <tt><a href= | ||||
| "./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting reverse iterator type  | ||||
| }; | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Example</h3> | ||||
|     In this example we sort a sequence of letters and then output the sequence | ||||
|     in descending order using reverse iterators.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| #include <boost/config.hpp> | ||||
| #include <iostream> | ||||
| #include <algorithm> | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   char letters[] = "hello world!"; | ||||
|   const int N = sizeof(letters)/sizeof(char) - 1; | ||||
|   std::cout << "original sequence of letters:\t" | ||||
|       << letters << std::endl; | ||||
|  | ||||
|   std::sort(letters, letters + N); | ||||
|  | ||||
|   // Use reverse_iterator_generator to print a sequence | ||||
|   // of letters in reverse order. | ||||
|    | ||||
|   boost::reverse_iterator_generator<char*>::type | ||||
|     reverse_letters_first(letters + N), | ||||
|     reverse_letters_last(letters); | ||||
|  | ||||
|   std::cout << "letters in descending order:\t"; | ||||
|   std::copy(reverse_letters_first, reverse_letters_last, | ||||
|       std::ostream_iterator<char>(std::cout)); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // to be continued... | ||||
| </pre> | ||||
|     </blockquote> | ||||
|     The output is:  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| original sequence of letters: hello world! | ||||
| letters in descending order:  wroolllhed!  | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Template Parameters</h3> | ||||
|  | ||||
|     <table border> | ||||
|       <tr> | ||||
|         <th>Parameter | ||||
|  | ||||
|         <th>Description | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt><a href= | ||||
|         "http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a></tt> | ||||
|          | ||||
|  | ||||
|         <td>The iterator type being wrapped. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Value</tt>  | ||||
|  | ||||
|         <td>The value-type of the base iterator and the resulting reverse | ||||
|         iterator.<br> | ||||
|          <b>Default:</b><tt>std::iterator_traits<BidirectionalIterator>::value_type</tt> | ||||
|          | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Reference</tt>  | ||||
|  | ||||
|         <td>The <tt>reference</tt> type of the resulting iterator, and in | ||||
|         particular, the result type of <tt>operator*()</tt>.<br> | ||||
|          <b>Default:</b> If <tt>Value</tt> is supplied, <tt>Value&</tt> is | ||||
|         used. Otherwise | ||||
|         <tt>std::iterator_traits<BidirectionalIterator>::reference</tt> | ||||
|         is used. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Pointer</tt>  | ||||
|  | ||||
|         <td>The <tt>pointer</tt> type of the resulting iterator, and in | ||||
|         particular, the result type of <tt>operator->()</tt>.<br> | ||||
|          <b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>, | ||||
|         otherwise | ||||
|         <tt>std::iterator_traits<BidirectionalIterator>::pointer</tt>. | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Category</tt>  | ||||
|  | ||||
|         <td>The <tt>iterator_category</tt> type for the resulting iterator.<br> | ||||
|          <b>Default:</b> | ||||
|         <tt>std::iterator_traits<BidirectionalIterator>::iterator_category</tt> | ||||
|          | ||||
|  | ||||
|       <tr> | ||||
|         <td><tt>Distance</tt>  | ||||
|  | ||||
|         <td>The <tt>difference_type</tt> for the resulting iterator.<br> | ||||
|          <b>Default:</b> | ||||
|         <tt>std::iterator_traits<BidirectionalIterator&gt::difference_type</tt> | ||||
|          | ||||
|     </table> | ||||
|  | ||||
|     <h3>Concept Model</h3> | ||||
|     The indirect iterator will model whichever <a href= | ||||
|     "http://www.sgi.com/tech/stl/Iterators.html">standard iterator concept | ||||
|     category</a> is modeled by the base iterator. Thus, if the base iterator is | ||||
|     a model of <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access | ||||
|     Iterator</a> then so is the resulting indirect iterator. If the base | ||||
|     iterator models a more restrictive concept, the resulting indirect iterator | ||||
|     will model the same concept. The base iterator must be at least a <a href= | ||||
|     "http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional | ||||
|     Iterator</a>  | ||||
|  | ||||
|     <h3>Members</h3> | ||||
|     The reverse iterator type implements the member functions and operators | ||||
|     required of the <a href= | ||||
|     "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access | ||||
|     Iterator</a> concept. In addition it has the following constructor:  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| reverse_iterator_generator::type(const BidirectionalIterator& it) | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|  | ||||
|     <br> | ||||
|      <br> | ||||
|       | ||||
|     <hr> | ||||
|  | ||||
|     <p> | ||||
|  | ||||
|     <h2><a name="make_reverse_iterator">The Reverse Iterator Object | ||||
|     Generator</a></h2> | ||||
|     The <tt>make_reverse_iterator()</tt> function provides a more convenient | ||||
|     way to create reverse iterator objects. The function saves the user the | ||||
|     trouble of explicitly writing out the iterator types.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| template <class BidirectionalIterator> | ||||
| typename reverse_iterator_generator<BidirectionalIterator>::type | ||||
| make_reverse_iterator(BidirectionalIterator base); | ||||
| </pre> | ||||
|     </blockquote> | ||||
|  | ||||
|     <h3>Example</h3> | ||||
|     In this part of the example we use <tt>make_reverse_iterator()</tt> to | ||||
|     print the sequence of letters in reverse-reverse order, which is the | ||||
|     original order.  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
|   // continuing from the previous example... | ||||
|  | ||||
|   std::cout << "letters in ascending order:\t"; | ||||
|   std::copy(boost::make_reverse_iterator(reverse_letters_last), | ||||
|       boost::make_reverse_iterator(reverse_letters_first), | ||||
|       std::ostream_iterator<char>(std::cout)); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| </pre> | ||||
|     </blockquote> | ||||
|     The output is:  | ||||
|  | ||||
|     <blockquote> | ||||
| <pre> | ||||
| letters in ascending order:  !dehllloorw | ||||
| </pre> | ||||
|     </blockquote> | ||||
|     <hr> | ||||
|  | ||||
|     <h2><a name="interactions">Constant/Mutable Iterator Interactions</a></h2> | ||||
|  | ||||
|     <p>One failing of the standard <tt><a | ||||
|     href="http://www.sgi.com/tech/stl/ReverseIterator.html">reverse_iterator</a></tt> | ||||
|     adaptor is that it doesn't properly support interactions between adapted | ||||
|     <tt>const</tt> and non-<tt>const</tt> iterators. For example: | ||||
| <blockquote> | ||||
| <pre> | ||||
| #include <vector> | ||||
|  | ||||
| template <class T> void convert(T x) {} | ||||
|  | ||||
| // Test interactions of a matched pair of random access iterators | ||||
| template <class Iterator, class ConstIterator> | ||||
| void test_interactions(Iterator i, ConstIterator ci) | ||||
| { | ||||
|   bool eq = i == ci;               // comparisons | ||||
|   bool ne = i != ci;             | ||||
|   bool lt = i < ci; | ||||
|   bool le = i <= ci; | ||||
|   bool gt = i > ci; | ||||
|   bool ge = i >= ci; | ||||
|   std::size_t distance = i - ci;   // difference | ||||
|   ci = i;                          // assignment | ||||
|   ConstIterator ci2(i);            // construction | ||||
|   convert<ConstIterator>(i);       // implicit conversion | ||||
| } | ||||
|  | ||||
| void f() | ||||
| { | ||||
|   typedef std::vector<int> vec; | ||||
|   vec v; | ||||
|   const vec& cv; | ||||
|  | ||||
|   test_interactions(v.begin(), cv.begin());   // <font color="#007F00">OK</font> | ||||
|   test_interactions(v.rbegin(), cv.rbegin()); // <font color="#FF0000">ERRORS ON EVERY TEST!!</font> | ||||
| </pre> | ||||
| </blockquote> | ||||
| Reverse iterators created with <tt>boost::reverse_iterator_generator</tt> don't have this problem, though: | ||||
| <blockquote> | ||||
| <pre> | ||||
|   typedef boost::reverse_iterator_generator<vec::iterator>::type ri; | ||||
|   typedef boost::reverse_iterator_generator<vec::const_iterator>::type cri; | ||||
|   test_interactions(ri(v.begin()), cri(cv.begin()));   // <font color="#007F00">OK!!</font> | ||||
| </pre> | ||||
| </blockquote> | ||||
| Or, more simply, | ||||
| <blockquote> | ||||
| <pre> | ||||
|   test_interactions( | ||||
|     boost::make_reverse_iterator(v.begin()),  | ||||
|     boost::make_reverse_iterator(cv.begin()));   // <font color="#007F00">OK!!</font> | ||||
| } | ||||
| </pre> | ||||
| </blockquote> | ||||
|  | ||||
| <p>If you are wondering why there is no | ||||
| <tt>reverse_iterator_pair_generator</tt> in the manner of <tt><a | ||||
| href="projection_iterator.htm#projection_iterator_pair_generator">projection_iterator_pair_generator</a></tt>, | ||||
| the answer is simple: we tried it, but found that in practice it took | ||||
| <i>more</i> typing to use <tt>reverse_iterator_pair_generator</tt> than to | ||||
| simply use <tt>reverse_iterator_generator</tt> twice!<br><br> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
|      | ||||
|     <p>Revised  | ||||
|     <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" --> | ||||
|  | ||||
|  | ||||
|     <p>© Copyright Jeremy Siek 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.  | ||||
|     <!--  LocalWords:  html charset alt gif hpp BidirectionalIterator const namespace struct | ||||
|          --> | ||||
|       | ||||
|     <!--  LocalWords:  ConstPointer ConstReference typename iostream int abcdefg | ||||
|          --> | ||||
|      <!--  LocalWords:  sizeof  PairGen pre Siek wroolllhed dehllloorw | ||||
|          --> | ||||
| </body> | ||||
| </html> | ||||
|  | ||||
| @@ -1,42 +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 <iostream> | ||||
| #include <algorithm> | ||||
| #include <boost/iterator_adaptors.hpp> | ||||
|  | ||||
| int main(int, char*[]) | ||||
| { | ||||
|   char letters[] = "hello world!"; | ||||
|   const int N = sizeof(letters)/sizeof(char) - 1; | ||||
|   std::cout << "original sequence of letters:\t" | ||||
| 	    << letters << std::endl; | ||||
|  | ||||
|   std::sort(letters, letters + N); | ||||
|  | ||||
|   // Use reverse_iterator_generator to print a sequence | ||||
|   // of letters in reverse order. | ||||
|    | ||||
|   boost::reverse_iterator_generator<char*>::type | ||||
|     reverse_letters_first(letters + N), | ||||
|     reverse_letters_last(letters); | ||||
|  | ||||
|   std::cout << "letters in descending order:\t"; | ||||
|   std::copy(reverse_letters_first, reverse_letters_last, | ||||
| 	    std::ostream_iterator<char>(std::cout)); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   // Use make_reverse_iterator() to print the sequence | ||||
|   // of letters in reverse-reverse order. | ||||
|  | ||||
|   std::cout << "letters in ascending order:\t"; | ||||
|   std::copy(boost::make_reverse_iterator(reverse_letters_last), | ||||
| 	    boost::make_reverse_iterator(reverse_letters_first), | ||||
| 	    std::ostream_iterator<char>(std::cout)); | ||||
|   std::cout << std::endl; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										322
									
								
								shared_container_iterator.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										322
									
								
								shared_container_iterator.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,322 @@ | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
| <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> | ||||
| <meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
| <title>Shared Container Iterator Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|  | ||||
| <img src="../../boost.png" alt="boost.png (6897 bytes)" | ||||
| align="center" width="277" height="86"> | ||||
|  | ||||
| <h1>Shared Container Iterator</h1> | ||||
|  | ||||
| Defined in header | ||||
| <a href="../../boost/shared_container_iterator.hpp">boost/shared_container_iterator.hpp</a> | ||||
|  | ||||
| <p> | ||||
| The purpose of the shared container iterator is to attach the lifetime | ||||
| of a container to the lifetime of its iterators. In other words, the | ||||
| container will not be deleted until after all its iterators are | ||||
| destroyed.  The shared container iterator is typically used to | ||||
| implement functions that return iterators over a range of objects that | ||||
| only need to exist for the lifetime of the iterators.  By returning a | ||||
| pair of shared iterators from a function, the callee can return a | ||||
| heap-allocated range of objects whose lifetime is automatically managed. | ||||
| <p> | ||||
| The shared container iterator augments an iterator over a shared | ||||
| container.  It maintains a reference count on the shared  | ||||
| container. If only shared container iterators hold references to | ||||
| the container, the container's lifetime will end when the last shared | ||||
| container iterator over it is destroyed.  In any case, the shared | ||||
| container is guaranteed to persist beyond the lifetime of all | ||||
| the iterators. In all other ways, the | ||||
| shared container iterator behaves the same as its base iterator. | ||||
|  | ||||
|  | ||||
| <h2>Synopsis</h2> | ||||
|  | ||||
| <pre> | ||||
| namespace boost { | ||||
|   template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>> | ||||
|   class shared_container_iterator; | ||||
|  | ||||
|   template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>> | ||||
|   shared_container_iterator<Container> | ||||
|   make_shared_container_iterator(typename Container::iterator base,  | ||||
|     boost::shared_ptr<Container> const& container); | ||||
|  | ||||
|   std::pair< | ||||
|     typename shared_container_iterator<Container>, | ||||
|     typename shared_container_iterator<Container> | ||||
|   > | ||||
|   make_shared_container_range(boost::shared_ptr<Container> const& container); | ||||
| } | ||||
| </pre> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <h2><a name="generator">The Shared Container Iterator Type</a></h2> | ||||
|  | ||||
| <pre> | ||||
| template <typename Container> class shared_container_iterator; | ||||
| </pre> | ||||
|  | ||||
| The class template <tt>shared_container_iterator</tt>  | ||||
| is the shared container iterator type.  The <tt>Container</tt> template | ||||
| type argument must model the | ||||
| <a href="http://www.sgi.com/tech/stl/Container.html">Container</a> | ||||
| concept. | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| <p> | ||||
| The following example illustrates how to create an iterator that  | ||||
| regulates the lifetime of a reference counted <tt>std::vector</tt>. | ||||
| Though the original shared pointer <tt>ints</tt> ceases to exist | ||||
| after <tt>set_range()</tt> returns, the | ||||
| <tt>shared_counter_iterator</tt> objects maintain references to the | ||||
|       underlying vector and thereby extend the container's lifetime. | ||||
| <p> | ||||
| <a href="./shared_iterator_example1.cpp">shared_iterator_example1.cpp</a>: | ||||
| <PRE> | ||||
| <font color="#008040">#include "shared_container_iterator.hpp"</font> | ||||
| <font color="#008040">#include "boost/shared_ptr.hpp"</font> | ||||
| <font color="#008040">#include <algorithm></font> | ||||
| <font color="#008040">#include <iostream></font> | ||||
| <font color="#008040">#include <vector></font> | ||||
|  | ||||
| <B>typedef</B> boost::shared_container_iterator< std::vector<<B>int</B>> > iterator; | ||||
|  | ||||
|  | ||||
| <B>void</B> set_range(iterator& i, iterator& end)  { | ||||
|  | ||||
|   boost::shared_ptr< std::vector<<B>int</B>> > ints(<B>new</B> std::vector<<B>int</B>>()); | ||||
|    | ||||
|   ints->push_back(<font color="#0000A0">0</font>); | ||||
|   ints->push_back(<font color="#0000A0">1</font>); | ||||
|   ints->push_back(<font color="#0000A0">2</font>); | ||||
|   ints->push_back(<font color="#0000A0">3</font>); | ||||
|   ints->push_back(<font color="#0000A0">4</font>); | ||||
|   ints->push_back(<font color="#0000A0">5</font>); | ||||
|    | ||||
|   i = iterator(ints->begin(),ints); | ||||
|   end = iterator(ints->end(),ints); | ||||
| } | ||||
|  | ||||
|  | ||||
| <B>int</B> main() { | ||||
|  | ||||
|   iterator i,end; | ||||
|  | ||||
|   set_range(i,end); | ||||
|  | ||||
|   std::copy(i,end,std::ostream_iterator<<B>int</B>>(std::cout,<font color="#0000FF">","</font>)); | ||||
|   std::cout.put(<font color="#0000FF">'\n'</font>); | ||||
|  | ||||
|   <B>return</B> <font color="#0000A0">0</font>; | ||||
| } | ||||
| </PRE> | ||||
|  | ||||
| The output from this part is: | ||||
| <pre> | ||||
| 0,1,2,3,4,5, | ||||
| </pre> | ||||
|  | ||||
| <h3>Template Parameters</h3> | ||||
|  | ||||
| <Table border> | ||||
| <TR> | ||||
| <TH>Parameter</TH><TH>Description</TH> | ||||
| </TR> | ||||
|  | ||||
| <TR> | ||||
| <TD><a | ||||
| href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a></TD> | ||||
| <TD>The type of the container that we wish to iterate over. It must be  | ||||
| a model of the  | ||||
| <a href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a> | ||||
| concept. | ||||
| </TD> | ||||
| </TR> | ||||
| </Table> | ||||
|  | ||||
| <h3>Model of</h3> | ||||
|  | ||||
| The <tt>shared_container_iterator<Container></tt> type models the | ||||
| same iterator concept as the base iterator | ||||
|     (<tt>Container::iterator</tt>). | ||||
|  | ||||
| <h3>Members</h3> | ||||
|  | ||||
| The shared container iterator type implements the member functions and | ||||
| operators required of the <a | ||||
| href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a> | ||||
| concept, though only operations defined for the base iterator will be valid. | ||||
| In addition it has the following constructor: | ||||
|  | ||||
| <pre> | ||||
| shared_container_iterator(Container::iterator const& it, | ||||
|                           boost::shared_ptr<Container> const& container) | ||||
| </pre> | ||||
|  | ||||
| <p> | ||||
| <hr> | ||||
| <p> | ||||
|  | ||||
|  | ||||
| <h2><a name="make_iterator">The Shared Container Iterator Object Generator</a></h2> | ||||
|  | ||||
| <pre> | ||||
| template <typename Container> | ||||
| shared_container_iterator<Container> | ||||
| make_shared_container_iterator(Container::iterator base, | ||||
|                                boost::shared_ptr<Container> const& container) | ||||
| </pre> | ||||
|  | ||||
| This function provides an alternative to directly constructing a | ||||
| shared container iterator.  Using the object generator, a shared | ||||
| container iterator can be created and passed to a function without | ||||
| explicitly specifying its type. | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| This example, similar to the previous, uses  | ||||
| <tt>make_shared_container_iterator()</tt> to create the iterators. | ||||
|  | ||||
| <p> | ||||
| <a href="./shared_iterator_example2.cpp">shared_iterator_example2.cpp</a>: | ||||
|  | ||||
| <PRE> | ||||
| <font color="#008040">#include "shared_container_iterator.hpp"</font> | ||||
| <font color="#008040">#include "boost/shared_ptr.hpp"</font> | ||||
| <font color="#008040">#include <algorithm></font> | ||||
| <font color="#008040">#include <iterator></font> | ||||
| <font color="#008040">#include <iostream></font> | ||||
| <font color="#008040">#include <vector></font> | ||||
|  | ||||
|  | ||||
| <B>template</B> <<B>typename</B> Iterator> | ||||
| <B>void</B> print_range_nl (Iterator begin, Iterator end) { | ||||
|   <B>typedef</B> <B>typename</B> std::iterator_traits<Iterator>::value_type val; | ||||
|   std::copy(begin,end,std::ostream_iterator<val>(std::cout,<font color="#0000FF">","</font>)); | ||||
|   std::cout.put(<font color="#0000FF">'\n'</font>); | ||||
| } | ||||
|  | ||||
|  | ||||
| <B>int</B> main() { | ||||
|  | ||||
|   <B>typedef</B> boost::shared_ptr< std::vector<<B>int</B>> > ints_t; | ||||
|   { | ||||
|     ints_t ints(<B>new</B> std::vector<<B>int</B>>()); | ||||
|  | ||||
|     ints->push_back(<font color="#0000A0">0</font>); | ||||
|     ints->push_back(<font color="#0000A0">1</font>); | ||||
|     ints->push_back(<font color="#0000A0">2</font>); | ||||
|     ints->push_back(<font color="#0000A0">3</font>); | ||||
|     ints->push_back(<font color="#0000A0">4</font>); | ||||
|     ints->push_back(<font color="#0000A0">5</font>); | ||||
|  | ||||
|     print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints), | ||||
| 		   boost::make_shared_container_iterator(ints->end(),ints)); | ||||
|   } | ||||
|    | ||||
|  | ||||
|  | ||||
|   <B>return</B> <font color="#0000A0">0</font>; | ||||
| } | ||||
| </PRE> | ||||
|  | ||||
| Observe that the <tt>shared_container_iterator</tt> type is never | ||||
| explicitly named. The output from this example is the same as the previous. | ||||
|  | ||||
| <h2><a name="make_range">The Shared Container Iterator Range Generator</a></h2> | ||||
|  | ||||
| <pre> | ||||
| template <typename Container> | ||||
| std::pair< | ||||
|   shared_container_iterator<Container>, | ||||
|   shared_container_iterator<Container> | ||||
| > | ||||
| make_shared_container_range(boost::shared_ptr<Container> const& container); | ||||
| </pre> | ||||
|  | ||||
| Class <tt>shared_container_iterator</tt> is meant primarily to return, | ||||
| using iterators, a range of values that we can guarantee will be alive as  | ||||
| long as the iterators are. This is a convenience | ||||
| function to do just that. It is equivalent to | ||||
|  | ||||
| <pre> | ||||
| std::make_pair(make_shared_container_iterator(container->begin(),container), | ||||
|                make_shared_container_iterator(container->end(),container)); | ||||
| </pre> | ||||
|  | ||||
| <h3>Example</h3> | ||||
|  | ||||
| In the following example, a range of values is returned as a pair of | ||||
| <tt>shared_container_iterator</tt> objects.   | ||||
|  | ||||
|  | ||||
| <p> | ||||
| <a href="./shared_iterator_example3.cpp">shared_iterator_example3.cpp</a>: | ||||
|  | ||||
| <PRE> | ||||
| <font color="#008040">#include "shared_container_iterator.hpp"</font> | ||||
| <font color="#008040">#include "boost/shared_ptr.hpp"</font> | ||||
| <font color="#008040">#include "boost/tuple/tuple.hpp" // for boost::tie</font> | ||||
| <font color="#008040">#include <algorithm>              // for std::copy</font> | ||||
| <font color="#008040">#include <iostream>              </font> | ||||
| <font color="#008040">#include <vector></font> | ||||
|  | ||||
|  | ||||
| <B>typedef</B> boost::shared_container_iterator< std::vector<<B>int</B>> > iterator;  | ||||
|  | ||||
| std::pair<iterator,iterator> | ||||
| return_range() { | ||||
|   boost::shared_ptr< std::vector<<B>int</B>> > range(<B>new</B> std::vector<<B>int</B>>()); | ||||
|   range->push_back(<font color="#0000A0">0</font>); | ||||
|   range->push_back(<font color="#0000A0">1</font>); | ||||
|   range->push_back(<font color="#0000A0">2</font>); | ||||
|   range->push_back(<font color="#0000A0">3</font>); | ||||
|   range->push_back(<font color="#0000A0">4</font>); | ||||
|   range->push_back(<font color="#0000A0">5</font>); | ||||
|   <B>return</B> boost::make_shared_container_range(range); | ||||
| } | ||||
|  | ||||
|  | ||||
| <B>int</B> main() { | ||||
|  | ||||
|  | ||||
|   iterator i,end; | ||||
|    | ||||
|   boost::tie(i,end) = return_range(); | ||||
|  | ||||
|   std::copy(i,end,std::ostream_iterator<<B>int</B>>(std::cout,<font color="#0000FF">","</font>)); | ||||
|   std::cout.put(<font color="#0000FF">'\n'</font>); | ||||
|  | ||||
|   <B>return</B> <font color="#0000A0">0</font>; | ||||
| } | ||||
| </PRE> | ||||
|  | ||||
| Though the <tt>range</tt> object only lives for the duration of the | ||||
| <tt>return_range</tt> call, the reference counted | ||||
| <tt>std::vector</tt> will live until <tt>i</tt> and <tt>end</tt> | ||||
| are both destroyed.  The output from this example is the same as | ||||
| the previous two. | ||||
|  | ||||
|  | ||||
| <hr> | ||||
| <!-- hhmts start --> | ||||
| Last modified: Mon Aug 11 11:27:03 EST 2003 | ||||
| <!-- hhmts end --> | ||||
| <p><EFBFBD> Copyright 2003 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)</p> | ||||
|  | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
							
								
								
									
										42
									
								
								shared_iterator_example1.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								shared_iterator_example1.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // Copyright 2003 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) | ||||
|  | ||||
| #include "boost/shared_container_iterator.hpp" | ||||
| #include "boost/shared_ptr.hpp" | ||||
| #include <algorithm> | ||||
| #include <iostream> | ||||
| #include <vector> | ||||
|  | ||||
| typedef boost::shared_container_iterator< std::vector<int> > iterator; | ||||
|  | ||||
|  | ||||
| void set_range(iterator& i, iterator& end)  { | ||||
|  | ||||
|   boost::shared_ptr< std::vector<int> > ints(new std::vector<int>()); | ||||
|    | ||||
|   ints->push_back(0); | ||||
|   ints->push_back(1); | ||||
|   ints->push_back(2); | ||||
|   ints->push_back(3); | ||||
|   ints->push_back(4); | ||||
|   ints->push_back(5); | ||||
|    | ||||
|   i = iterator(ints->begin(),ints); | ||||
|   end = iterator(ints->end(),ints); | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() { | ||||
|  | ||||
|   iterator i,end; | ||||
|  | ||||
|   set_range(i,end); | ||||
|  | ||||
|   std::copy(i,end,std::ostream_iterator<int>(std::cout,",")); | ||||
|   std::cout.put('\n'); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										43
									
								
								shared_iterator_example2.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								shared_iterator_example2.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| // Copyright 2003 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) | ||||
|  | ||||
| #include "boost/shared_container_iterator.hpp" | ||||
| #include "boost/shared_ptr.hpp" | ||||
| #include <algorithm> | ||||
| #include <iterator> | ||||
| #include <iostream> | ||||
| #include <vector> | ||||
|  | ||||
|  | ||||
| template <typename Iterator> | ||||
| void print_range_nl (Iterator begin, Iterator end) { | ||||
|   typedef typename std::iterator_traits<Iterator>::value_type val; | ||||
|   std::copy(begin,end,std::ostream_iterator<val>(std::cout,",")); | ||||
|   std::cout.put('\n'); | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() { | ||||
|  | ||||
|   typedef boost::shared_ptr< std::vector<int> > ints_t; | ||||
|   { | ||||
|     ints_t ints(new std::vector<int>()); | ||||
|  | ||||
|     ints->push_back(0); | ||||
|     ints->push_back(1); | ||||
|     ints->push_back(2); | ||||
|     ints->push_back(3); | ||||
|     ints->push_back(4); | ||||
|     ints->push_back(5); | ||||
|  | ||||
|     print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints), | ||||
|                    boost::make_shared_container_iterator(ints->end(),ints)); | ||||
|   } | ||||
|    | ||||
|  | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										41
									
								
								shared_iterator_example3.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								shared_iterator_example3.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| // Copyright 2003 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) | ||||
|  | ||||
| #include "boost/shared_container_iterator.hpp" | ||||
| #include "boost/shared_ptr.hpp" | ||||
| #include "boost/tuple/tuple.hpp" // for boost::tie | ||||
| #include <algorithm>              // for std::copy | ||||
| #include <iostream>               | ||||
| #include <vector> | ||||
|  | ||||
|  | ||||
| typedef boost::shared_container_iterator< std::vector<int> > iterator; | ||||
|  | ||||
| std::pair<iterator,iterator> | ||||
| return_range() { | ||||
|   boost::shared_ptr< std::vector<int> > range(new std::vector<int>()); | ||||
|   range->push_back(0); | ||||
|   range->push_back(1); | ||||
|   range->push_back(2); | ||||
|   range->push_back(3); | ||||
|   range->push_back(4); | ||||
|   range->push_back(5); | ||||
|   return boost::make_shared_container_range(range); | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() { | ||||
|  | ||||
|  | ||||
|   iterator i,end; | ||||
|    | ||||
|   boost::tie(i,end) = return_range(); | ||||
|  | ||||
|   std::copy(i,end,std::ostream_iterator<int>(std::cout,",")); | ||||
|   std::cout.put('\n'); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										64
									
								
								shared_iterator_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								shared_iterator_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| // Copyright 2003 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) | ||||
|  | ||||
| //  Shared container iterator adaptor  | ||||
| //  Author: Ronald Garcia | ||||
| //  See http://boost.org/libs/utility/shared_container_iterator.html  | ||||
| //  for documentation.  | ||||
|  | ||||
| // | ||||
| // shared_iterator_test.cpp - Regression tests for shared_container_iterator. | ||||
| // | ||||
|  | ||||
|  | ||||
| #include "boost/shared_container_iterator.hpp" | ||||
| #include "boost/shared_ptr.hpp" | ||||
| #include <vector> | ||||
| #include <cassert> | ||||
|  | ||||
| struct resource { | ||||
|   static int count; | ||||
|   resource() { ++count; } | ||||
|   resource(resource const&) { ++count; } | ||||
|   ~resource() { --count; } | ||||
| }; | ||||
| int resource::count = 0; | ||||
|  | ||||
| typedef std::vector<resource> resources_t; | ||||
|  | ||||
| typedef boost::shared_container_iterator< resources_t > iterator; | ||||
|  | ||||
|  | ||||
| void set_range(iterator& i, iterator& end)  { | ||||
|  | ||||
|   boost::shared_ptr< resources_t > objs(new resources_t()); | ||||
|  | ||||
|   for (int j = 0; j != 6; ++j) | ||||
|     objs->push_back(resource()); | ||||
|    | ||||
|   i = iterator(objs->begin(),objs); | ||||
|   end = iterator(objs->end(),objs); | ||||
|   assert(resource::count == 6); | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() { | ||||
|  | ||||
|   assert(resource::count == 0); | ||||
|    | ||||
|   { | ||||
|     iterator i; | ||||
|     { | ||||
|       iterator end; | ||||
|       set_range(i,end); | ||||
|       assert(resource::count == 6); | ||||
|     } | ||||
|     assert(resource::count == 6); | ||||
|   } | ||||
|   assert(resource::count == 0); | ||||
|    | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										1
									
								
								sublibs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								sublibs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| The existance of this file tells the regression reporting programs that the directory contains sub-directories which are libraries. | ||||
							
								
								
									
										38
									
								
								test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| # Copyright David Abrahams 2003. | ||||
|  | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # See http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| # For more information, see http://www.boost.org/ | ||||
|  | ||||
| # bring in rules for testing | ||||
| import testing ; | ||||
|  | ||||
| # Please keep the tests ordered by filename | ||||
| test-suite utility | ||||
|     : | ||||
|         [ run ../addressof_test.cpp ] | ||||
|         [ run ../assert_test.cpp ] | ||||
|         [ run ../base_from_member_test.cpp ] | ||||
|         [ run ../binary_search_test.cpp ] | ||||
|         [ run ../binary_test.cpp ] | ||||
|         [ run ../call_traits_test.cpp : -u ] | ||||
|         [ compile-fail ../checked_delete_test.cpp ] | ||||
|         [ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static : -u ] | ||||
|         [ run ../current_function_test.cpp : : : <test-info>always_show_run_output ] | ||||
|         [ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ] | ||||
|         [ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ] | ||||
|         [ compile-fail ../noncopyable_test.cpp ] | ||||
|         [ run ../numeric_traits_test.cpp ] | ||||
|         [ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ] | ||||
|         [ compile ../ref_ct_test.cpp  ] | ||||
|         [ run ../ref_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ] | ||||
|         [ compile result_of_test.cpp ] | ||||
|         [ run ../shared_iterator_test.cpp ] | ||||
|         [ run ../value_init_test.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail1.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail2.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail3.cpp ] | ||||
|         [ run ../verify_test.cpp ] | ||||
|     ; | ||||
|  | ||||
							
								
								
									
										79
									
								
								test/next_prior_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								test/next_prior_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| // Boost test program for next() and prior() utilities. | ||||
|  | ||||
| // Copyright 2003 Daniel 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 documentation. | ||||
|  | ||||
| // Revision History 13 Dec 2003 Initial Version (Daniel Walker) | ||||
|  | ||||
| // next() and prior() are replacements for operator+ and operator- for | ||||
| // non-random-access iterators. The semantics of these operators are | ||||
| // such that after executing j = i + n, std::distance(i, j) equals | ||||
| // n. Tests are provided to ensure next() has the same | ||||
| // result. Parallel tests are provided for prior(). The tests call | ||||
| // next() and prior() several times. next() and prior() are very | ||||
| // simple functions, though, and it would be very strange if these | ||||
| // tests were to fail. | ||||
|  | ||||
| #define BOOST_INCLUDE_MAIN | ||||
| #include <boost/test/test_tools.hpp> | ||||
|  | ||||
| #include <list> | ||||
| #include <vector> | ||||
|  | ||||
| #include <boost/next_prior.hpp> | ||||
|  | ||||
| template<class RandomAccessIterator, class ForwardIterator> | ||||
| bool plus_one_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2) | ||||
| { | ||||
|     RandomAccessIterator i = first; | ||||
|     ForwardIterator j = first2; | ||||
|     while(i != last) | ||||
|         i = i + 1, j = boost::next(j); | ||||
|     return std::distance(first, i) == std::distance(first2, j); | ||||
| } | ||||
|  | ||||
| template<class RandomAccessIterator, class ForwardIterator> | ||||
| bool plus_n_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2) | ||||
| { | ||||
|     RandomAccessIterator i = first; | ||||
|     ForwardIterator j = first2; | ||||
|     for(int n = 0; i != last; ++n) | ||||
|         i = first + n, j = boost::next(first2, n); | ||||
|     return std::distance(first, i) == std::distance(first2, j); | ||||
| } | ||||
|  | ||||
| template<class RandomAccessIterator, class BidirectionalIterator> | ||||
| bool minus_one_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2) | ||||
| { | ||||
|     RandomAccessIterator i = last; | ||||
|     BidirectionalIterator j = last2; | ||||
|     while(i != first) | ||||
|         i = i - 1, j = boost::prior(j); | ||||
|     return std::distance(i, last) == std::distance(j, last2); | ||||
| } | ||||
|  | ||||
| template<class RandomAccessIterator, class BidirectionalIterator> | ||||
| bool minus_n_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2) | ||||
| { | ||||
|     RandomAccessIterator i = last; | ||||
|     BidirectionalIterator j = last2; | ||||
|     for(int n = 0; i != first; ++n) | ||||
|         i = last - n, j = boost::prior(last2, n); | ||||
|     return std::distance(i, last) == std::distance(j, last2); | ||||
| } | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|     std::vector<int> x(8); | ||||
|     std::list<int> y(x.begin(), x.end()); | ||||
|  | ||||
|     BOOST_REQUIRE(plus_one_test(x.begin(), x.end(), y.begin())); | ||||
|     BOOST_REQUIRE(plus_n_test(x.begin(), x.end(), y.begin())); | ||||
|     BOOST_REQUIRE(minus_one_test(x.begin(), x.end(), y.end())); | ||||
|     BOOST_REQUIRE(minus_n_test(x.begin(), x.end(), y.end())); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										85
									
								
								test/result_of_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								test/result_of_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| // Boost result_of library | ||||
|  | ||||
| //  Copyright Douglas Gregor 2003-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 | ||||
| #include <boost/utility/result_of.hpp> | ||||
| #include <utility> | ||||
| #include <boost/static_assert.hpp> | ||||
| #include <boost/type_traits/is_same.hpp> | ||||
|  | ||||
| struct int_result_type { typedef int result_type; }; | ||||
|  | ||||
| struct int_result_of | ||||
| { | ||||
|   template<typename F> struct result { typedef int type; }; | ||||
| }; | ||||
|  | ||||
| struct int_result_type_and_float_result_of | ||||
| { | ||||
|   typedef int result_type; | ||||
|   template<typename F> struct result { typedef float type; }; | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| struct int_result_type_template { typedef int result_type; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct int_result_of_template | ||||
| { | ||||
|   template<typename F> struct result; | ||||
|   template<typename This, typename That> struct result<This(That)> { typedef int type; }; | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| struct int_result_type_and_float_result_of_template | ||||
| { | ||||
|   typedef int result_type; | ||||
|   template<typename F> struct result; | ||||
|   template<typename This, typename That> struct result<This(That)> { typedef float type; }; | ||||
| }; | ||||
|  | ||||
| struct X {}; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   using namespace boost; | ||||
|  | ||||
|   typedef int (*func_ptr)(float, double); | ||||
|   typedef int (&func_ref)(float, double); | ||||
|   typedef int (*func_ptr_0)(); | ||||
|   typedef int (&func_ref_0)(); | ||||
|   typedef int (X::*mem_func_ptr)(float); | ||||
|   typedef int (X::*mem_func_ptr_c)(float) const; | ||||
|   typedef int (X::*mem_func_ptr_v)(float) volatile; | ||||
|   typedef int (X::*mem_func_ptr_cv)(float) const volatile; | ||||
|   typedef int (X::*mem_func_ptr_0)(); | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of(char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_template<void>(float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_template<void>(char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value));  | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ref_0()>::type, int>::value));  | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));  | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(void)>::type, int>::value)); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user