mirror of
				https://github.com/boostorg/utility.git
				synced 2025-11-04 02:11:45 +01:00 
			
		
		
		
	Compare commits
	
		
			547 Commits
		
	
	
		
			svn-branch
			...
			svn-branch
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e7cdd8e6dc | ||
| 
						 | 
					cefd52543b | ||
| 
						 | 
					5a94dd1bf0 | ||
| 
						 | 
					96d573d6ca | ||
| 
						 | 
					2412b864d6 | ||
| 
						 | 
					94865eabe6 | ||
| 
						 | 
					50268d1b29 | ||
| 
						 | 
					ad9108c1dc | ||
| 
						 | 
					691e4b6c34 | ||
| 
						 | 
					28596e678d | ||
| 
						 | 
					1beca24dd8 | ||
| 
						 | 
					721764937f | ||
| 
						 | 
					a511007d0f | ||
| 
						 | 
					8ce58b1675 | ||
| 
						 | 
					9ed68b8321 | ||
| 
						 | 
					79bbf71d0d | ||
| 
						 | 
					ac93de7c1b | ||
| 
						 | 
					d731b8e1c5 | ||
| 
						 | 
					ac1567b3fc | ||
| 
						 | 
					c1fd670480 | ||
| 
						 | 
					01274cf6ac | ||
| 
						 | 
					8080673977 | ||
| 
						 | 
					a470b591fb | ||
| 
						 | 
					e1a63495b6 | ||
| 
						 | 
					7300ac83f1 | ||
| 
						 | 
					882d38c2c7 | ||
| 
						 | 
					33041ad664 | ||
| 
						 | 
					6a2aa822f8 | ||
| 
						 | 
					09ab16bfc1 | ||
| 
						 | 
					ec46e40809 | ||
| 
						 | 
					b3a971e7e9 | ||
| 
						 | 
					7ddb559887 | ||
| 
						 | 
					ea8c99b1d5 | ||
| 
						 | 
					56b0846099 | ||
| 
						 | 
					42e0001370 | ||
| 
						 | 
					cd8f85afee | ||
| 
						 | 
					bddd52c4b9 | ||
| 
						 | 
					8f03aeac4e | ||
| 
						 | 
					3bb2568fad | ||
| 
						 | 
					01e91a3799 | ||
| 
						 | 
					55f3c351a3 | ||
| 
						 | 
					3f72b10182 | ||
| 
						 | 
					71cb8cb574 | ||
| 
						 | 
					c950825ef4 | ||
| 
						 | 
					66ca84a45d | ||
| 
						 | 
					06404f7d39 | ||
| 
						 | 
					2d860e2574 | ||
| 
						 | 
					66514f61ff | ||
| 
						 | 
					63cde4d3fd | ||
| 
						 | 
					1950f292df | ||
| 
						 | 
					92a0602190 | ||
| 
						 | 
					c9a3ab1d04 | ||
| 
						 | 
					0782034333 | ||
| 
						 | 
					0808883f3c | ||
| 
						 | 
					2f69501e55 | ||
| 
						 | 
					5b83f641a8 | ||
| 
						 | 
					c730ab4ffb | ||
| 
						 | 
					e55610a0d0 | ||
| 
						 | 
					bf968794c9 | ||
| 
						 | 
					ce6e9c6698 | ||
| 
						 | 
					7ac180ed54 | ||
| 
						 | 
					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 | ||
| 
						 | 
					feb370b201 | ||
| 
						 | 
					d1b34e64d8 | ||
| 
						 | 
					b9a1eead40 | ||
| 
						 | 
					1e4bfac98c | ||
| 
						 | 
					3bb504fbf3 | ||
| 
						 | 
					5029791c90 | ||
| 
						 | 
					a1a68f0970 | ||
| 
						 | 
					f8543d79eb | ||
| 
						 | 
					f353415136 | ||
| 
						 | 
					26240403b0 | ||
| 
						 | 
					3a39729b58 | ||
| 
						 | 
					096c961d9a | ||
| 
						 | 
					01fe04a6a2 | ||
| 
						 | 
					7ea4014993 | ||
| 
						 | 
					d50b374f88 | ||
| 
						 | 
					27dfb25570 | ||
| 
						 | 
					b5ed77985e | ||
| 
						 | 
					61243bd15f | ||
| 
						 | 
					368b94d804 | ||
| 
						 | 
					a5adbbfd5f | ||
| 
						 | 
					a19d13f123 | ||
| 
						 | 
					78886ab383 | ||
| 
						 | 
					168012b465 | ||
| 
						 | 
					d9d58ea66e | ||
| 
						 | 
					56f5f6e8d5 | ||
| 
						 | 
					3cb6420eda | ||
| 
						 | 
					60be2c1186 | ||
| 
						 | 
					ed210f6b2c | ||
| 
						 | 
					029bc59d74 | ||
| 
						 | 
					961c08a82f | ||
| 
						 | 
					7ee484c614 | ||
| 
						 | 
					05c6fbbf99 | ||
| 
						 | 
					91078b7f7a | ||
| 
						 | 
					20d804afc4 | ||
| 
						 | 
					c21f6d1cbf | ||
| 
						 | 
					393e79c1fd | ||
| 
						 | 
					8b92c8a085 | ||
| 
						 | 
					ff73dd94c9 | ||
| 
						 | 
					af43904f38 | ||
| 
						 | 
					485074f265 | ||
| 
						 | 
					2e0ee55b5e | ||
| 
						 | 
					e9105d32cb | ||
| 
						 | 
					964d23f68c | ||
| 
						 | 
					be5aaaae7b | ||
| 
						 | 
					bf13bd7b3f | ||
| 
						 | 
					352e392fcb | ||
| 
						 | 
					083b1b02df | ||
| 
						 | 
					648c6240a2 | ||
| 
						 | 
					60cab840cb | ||
| 
						 | 
					83a4380dab | ||
| 
						 | 
					de84fe8d98 | ||
| 
						 | 
					ed3cbfdb8e | ||
| 
						 | 
					fda44ca17d | ||
| 
						 | 
					272025bb07 | ||
| 
						 | 
					8e92bcf1b2 | ||
| 
						 | 
					84f1ffdefe | ||
| 
						 | 
					7e25450054 | ||
| 
						 | 
					4a563fa266 | ||
| 
						 | 
					aa4c0ec000 | ||
| 
						 | 
					e1ecfbdc43 | ||
| 
						 | 
					a4e122a82e | ||
| 
						 | 
					93216e8fb7 | ||
| 
						 | 
					16272c210d | ||
| 
						 | 
					e104b00da1 | ||
| 
						 | 
					ce5c6bcc08 | ||
| 
						 | 
					8694ce31fe | ||
| 
						 | 
					d960e5eadd | ||
| 
						 | 
					2dc71e87a3 | ||
| 
						 | 
					6bf17edde2 | ||
| 
						 | 
					88573d515d | ||
| 
						 | 
					89b9f77823 | ||
| 
						 | 
					765d9be17d | ||
| 
						 | 
					7135373008 | ||
| 
						 | 
					ee269884fc | ||
| 
						 | 
					387540d5f1 | ||
| 
						 | 
					2eba7b42a8 | ||
| 
						 | 
					07115d26c7 | ||
| 
						 | 
					c43ed815a0 | ||
| 
						 | 
					ff01e36d12 | ||
| 
						 | 
					ac4798b16c | ||
| 
						 | 
					d4e14fed0e | ||
| 
						 | 
					5f91259344 | ||
| 
						 | 
					20a9d9645d | ||
| 
						 | 
					c86f6b4abd | ||
| 
						 | 
					d66489b5b2 | ||
| 
						 | 
					b743ee9f0c | ||
| 
						 | 
					95ba69c00a | ||
| 
						 | 
					2ac273739c | ||
| 
						 | 
					5b4d28708c | ||
| 
						 | 
					4cc4383488 | ||
| 
						 | 
					8935232248 | ||
| 
						 | 
					5c6dd2f172 | ||
| 
						 | 
					eeeb7ef5b9 | ||
| 
						 | 
					2efc9c1178 | ||
| 
						 | 
					a84c46f6e3 | ||
| 
						 | 
					a5c3dcdd02 | ||
| 
						 | 
					46f7a75eb7 | ||
| 
						 | 
					94b6710c5b | ||
| 
						 | 
					d8dd3da9ab | ||
| 
						 | 
					803ced004a | ||
| 
						 | 
					0ea7d36ad0 | ||
| 
						 | 
					87aafab759 | ||
| 
						 | 
					994d310abd | ||
| 
						 | 
					228cdcf05e | ||
| 
						 | 
					42598e352c | ||
| 
						 | 
					36a9e4d1da | ||
| 
						 | 
					456dfd0dea | ||
| 
						 | 
					155457e2b5 | ||
| 
						 | 
					b5c91485bf | ||
| 
						 | 
					c959cf7870 | ||
| 
						 | 
					5878c88636 | ||
| 
						 | 
					ddcef2fb19 | ||
| 
						 | 
					493d124c07 | ||
| 
						 | 
					f42060c616 | ||
| 
						 | 
					834facc932 | ||
| 
						 | 
					f82d0b76ee | ||
| 
						 | 
					c25d225275 | ||
| 
						 | 
					c503a274b5 | ||
| 
						 | 
					087069d215 | ||
| 
						 | 
					826a6dd114 | ||
| 
						 | 
					f31483838d | ||
| 
						 | 
					d8a9b633d9 | ||
| 
						 | 
					c060e4466a | ||
| 
						 | 
					a9951376f4 | ||
| 
						 | 
					bda0c8f5e3 | ||
| 
						 | 
					71902f23a2 | ||
| 
						 | 
					dfd6c85569 | ||
| 
						 | 
					0e41b2cc1a | ||
| 
						 | 
					e5c81d0702 | ||
| 
						 | 
					6caf7d4d5a | ||
| 
						 | 
					98e87c8afb | ||
| 
						 | 
					d9e0f80d50 | ||
| 
						 | 
					6396fdb5ff | ||
| 
						 | 
					2470b53373 | ||
| 
						 | 
					16334e92ca | ||
| 
						 | 
					c22d98a8ec | ||
| 
						 | 
					28617afbb9 | ||
| 
						 | 
					0c3bc42bec | ||
| 
						 | 
					e3d9745df1 | 
							
								
								
									
										109
									
								
								Assignable.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								Assignable.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
<!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>Assignable</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<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>Assignable</h1>
 | 
			
		||||
 | 
			
		||||
  <h3>Description</h3>
 | 
			
		||||
 | 
			
		||||
  <p>A type is Assignable if it is possible to assign one object of the type
 | 
			
		||||
  to another object of that type.</p>
 | 
			
		||||
 | 
			
		||||
  <h3>Notation</h3>
 | 
			
		||||
 | 
			
		||||
  <table summary="">
 | 
			
		||||
    <tr>
 | 
			
		||||
      <td valign="top"><tt>T</tt></td>
 | 
			
		||||
 | 
			
		||||
      <td valign="top">is type that is a model of Assignable</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>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>
 | 
			
		||||
							
								
								
									
										185
									
								
								CopyConstructible.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								CopyConstructible.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
<!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>Copy Constructible</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<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>Copy Constructible</h1>
 | 
			
		||||
 | 
			
		||||
  <h3>Description</h3>
 | 
			
		||||
 | 
			
		||||
  <p>A type is Copy Constructible if it is possible to copy objects of that
 | 
			
		||||
  type.</p>
 | 
			
		||||
 | 
			
		||||
  <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>
 | 
			
		||||
 | 
			
		||||
    <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>
 | 
			
		||||
 | 
			
		||||
    <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>
 | 
			
		||||
 | 
			
		||||
    <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>
 | 
			
		||||
  </table>
 | 
			
		||||
 | 
			
		||||
  <h3>Models</h3>
 | 
			
		||||
 | 
			
		||||
  <ul>
 | 
			
		||||
    <li><tt>int</tt></li>
 | 
			
		||||
 | 
			
		||||
    <li><tt>std::pair</tt></li>
 | 
			
		||||
  </ul>
 | 
			
		||||
 | 
			
		||||
  <h3>Concept Checking Class</h3>
 | 
			
		||||
  <pre>
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct CopyConstructibleConcept
 | 
			
		||||
  {
 | 
			
		||||
    void constraints() {
 | 
			
		||||
      T a(b);            // require copy constructor
 | 
			
		||||
      T* ptr = &a;       // require address of operator
 | 
			
		||||
      const_constraints(a);
 | 
			
		||||
      ignore_unused_variable_warning(ptr);
 | 
			
		||||
    }
 | 
			
		||||
    void const_constraints(const T& a) {
 | 
			
		||||
      T c(a);            // require const copy constructor
 | 
			
		||||
      const T* ptr = &a; // require const address of operator
 | 
			
		||||
      ignore_unused_variable_warning(c);
 | 
			
		||||
      ignore_unused_variable_warning(ptr);
 | 
			
		||||
    }
 | 
			
		||||
    T b;
 | 
			
		||||
  };
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
  <h3>See also</h3>
 | 
			
		||||
 | 
			
		||||
  <p><a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default
 | 
			
		||||
  Constructible</a> and <a href="./Assignable.html">Assignable</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>
 | 
			
		||||
							
								
								
									
										210
									
								
								LessThanComparable.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								LessThanComparable.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
 | 
			
		||||
<html>
 | 
			
		||||
<!--
 | 
			
		||||
  == 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>
 | 
			
		||||
  <meta http-equiv="Content-Language" content="en-us">
 | 
			
		||||
  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
 | 
			
		||||
 | 
			
		||||
  <title>LessThanComparable</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
  <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>Associated types</h3>
 | 
			
		||||
 | 
			
		||||
  <h3>Notation</h3>
 | 
			
		||||
 | 
			
		||||
  <table summary="">
 | 
			
		||||
    <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>
 | 
			
		||||
 | 
			
		||||
  <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>
 | 
			
		||||
							
								
								
									
										95
									
								
								MultiPassInputIterator.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								MultiPassInputIterator.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
<!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>MultiPassInputIterator</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
  <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>
 | 
			
		||||
 | 
			
		||||
  <h3>Design Notes</h3>
 | 
			
		||||
 | 
			
		||||
  <p>comments by Valentin Bonnard:</p>
 | 
			
		||||
 | 
			
		||||
  <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>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>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>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>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>
 | 
			
		||||
 | 
			
		||||
  <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>
 | 
			
		||||
							
								
								
									
										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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										755
									
								
								call_traits.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										755
									
								
								call_traits.htm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,755 @@
 | 
			
		||||
<html>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type"
 | 
			
		||||
content="text/html; charset=iso-8859-1">
 | 
			
		||||
<meta name="Template"
 | 
			
		||||
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
 | 
			
		||||
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
 | 
			
		||||
<title>Call Traits</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
 | 
			
		||||
vlink="#800080">
 | 
			
		||||
 | 
			
		||||
<h1><img src="../../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
 | 
			
		||||
defined inside namespace boost.</p>
 | 
			
		||||
 | 
			
		||||
<p>The template class call_traits<T> encapsulates the
 | 
			
		||||
"best" method to pass a parameter of some type T to or
 | 
			
		||||
from a function, and consists of a collection of typedefs defined
 | 
			
		||||
as in the table below. The purpose of call_traits is to ensure
 | 
			
		||||
that problems like "<a href="#refs">references to references</a>"
 | 
			
		||||
never occur, and that parameters are passed in the most efficient
 | 
			
		||||
manner possible (see <a href="#examples">examples</a>). In each
 | 
			
		||||
case if your existing practice is to use the type defined on the
 | 
			
		||||
left, then replace it with the call_traits defined type on the
 | 
			
		||||
right. </p>
 | 
			
		||||
 | 
			
		||||
<p>Note that for compilers that do not support either partial
 | 
			
		||||
specialization or member templates, no benefit will occur from
 | 
			
		||||
using call_traits: the call_traits defined types will always be
 | 
			
		||||
the same as the existing practice in this case. In addition if
 | 
			
		||||
only member templates and not partial template specialisation is
 | 
			
		||||
support by the compiler (for example Visual C++ 6) then
 | 
			
		||||
call_traits can not be used with array types (although it can be
 | 
			
		||||
used to solve the reference to reference problem).</p>
 | 
			
		||||
 | 
			
		||||
<table border="0" cellpadding="7" cellspacing="1" width="797">
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#008080"><p
 | 
			
		||||
        align="center">Existing practice</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="35%" bgcolor="#008080"><p
 | 
			
		||||
        align="center">call_traits equivalent</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="32%" bgcolor="#008080"><p
 | 
			
		||||
        align="center">Description</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="16%" bgcolor="#008080"><p
 | 
			
		||||
        align="center">Notes</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">T<br>
 | 
			
		||||
        (return by value)</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="35%"><p align="center"><code>call_traits<T>::value_type</code></p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="32%">Defines a type that
 | 
			
		||||
        represents the "value" of type T. Use this for
 | 
			
		||||
        functions that return by value, or possibly for stored
 | 
			
		||||
        values of type T.</td>
 | 
			
		||||
        <td valign="top" width="16%"><p align="center">2</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">T&<br>
 | 
			
		||||
        (return value)</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="35%"><p align="center"><code>call_traits<T>::reference</code></p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="32%">Defines a type that
 | 
			
		||||
        represents a reference to type T. Use for functions that
 | 
			
		||||
        would normally return a T&.</td>
 | 
			
		||||
        <td valign="top" width="16%"><p align="center">1</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        T&<br>
 | 
			
		||||
        (return value)</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="35%"><p align="center"><code>call_traits<T>::const_reference</code></p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="32%">Defines a type that
 | 
			
		||||
        represents a constant reference to type T. Use for
 | 
			
		||||
        functions that would normally return a const T&.</td>
 | 
			
		||||
        <td valign="top" width="16%"><p align="center">1</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        T&<br>
 | 
			
		||||
        (function parameter)</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="35%"><p align="center"><code>call_traits<T>::param_type</code></p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="32%">Defines a type that
 | 
			
		||||
        represents the "best" way to pass a parameter
 | 
			
		||||
        of type T to a function.</td>
 | 
			
		||||
        <td valign="top" width="16%"><p align="center">1,3</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<p>Notes:</p>
 | 
			
		||||
 | 
			
		||||
<ol>
 | 
			
		||||
    <li>If T is already reference type, then call_traits is
 | 
			
		||||
        defined such that <a href="#refs">references to
 | 
			
		||||
        references</a> do not occur (requires partial
 | 
			
		||||
        specialization).</li>
 | 
			
		||||
    <li>If T is an array type, then call_traits defines <code>value_type</code>
 | 
			
		||||
        as a "constant pointer to type" rather than an
 | 
			
		||||
        "array of type" (requires partial
 | 
			
		||||
        specialization). Note that if you are using value_type as
 | 
			
		||||
        a stored value then this will result in storing a "constant
 | 
			
		||||
        pointer to an array" rather than the array itself.
 | 
			
		||||
        This may or may not be a good thing depending upon what
 | 
			
		||||
        you actually need (in other words take care!).</li>
 | 
			
		||||
    <li>If T is a small built in type or a pointer, then <code>param_type</code>
 | 
			
		||||
        is defined as <code>T const</code>, instead of <code>T
 | 
			
		||||
        const&</code>. This can improve the ability of the
 | 
			
		||||
        compiler to optimize loops in the body of the function if
 | 
			
		||||
        they depend upon the passed parameter, the semantics of
 | 
			
		||||
        the passed parameter is otherwise unchanged (requires
 | 
			
		||||
        partial specialization).</li>
 | 
			
		||||
</ol>
 | 
			
		||||
 | 
			
		||||
<p> </p>
 | 
			
		||||
 | 
			
		||||
<h3>Copy constructibility</h3>
 | 
			
		||||
 | 
			
		||||
<p>The following table defines which call_traits types can always
 | 
			
		||||
be copy-constructed from which other types, those entries marked
 | 
			
		||||
with a '?' are true only if and only if T is copy constructible:</p>
 | 
			
		||||
 | 
			
		||||
<table border="0" cellpadding="7" cellspacing="1" width="766">
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%"> </td>
 | 
			
		||||
        <td valign="top" colspan="5" width="85%"
 | 
			
		||||
        bgcolor="#008080"><p align="center">To:</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#008080">From:</td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">T</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">value_type</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">reference</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">const_reference</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">param_type</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">N</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">N</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">N</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">N</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">?</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">N</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">N</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<p> </p>
 | 
			
		||||
 | 
			
		||||
<p>If T is an assignable type the following assignments are
 | 
			
		||||
possible:</p>
 | 
			
		||||
 | 
			
		||||
<table border="0" cellpadding="7" cellspacing="1" width="766">
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%"> </td>
 | 
			
		||||
        <td valign="top" colspan="5" width="85%"
 | 
			
		||||
        bgcolor="#008080"><p align="center">To:</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#008080">From:</td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">T</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">value_type</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">reference</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">const_reference</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">param_type</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">Y</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">-</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<p> </p>
 | 
			
		||||
 | 
			
		||||
<h3><a name="examples"></a>Examples</h3>
 | 
			
		||||
 | 
			
		||||
<p>The following table shows the effect that call_traits has on
 | 
			
		||||
various types, the table assumes that the compiler supports
 | 
			
		||||
partial specialization: if it doesn't then all types behave in
 | 
			
		||||
the same way as the entry for "myclass", and
 | 
			
		||||
call_traits can not be used with reference or array types.</p>
 | 
			
		||||
 | 
			
		||||
<table border="0" cellpadding="7" cellspacing="1" width="766">
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%"> </td>
 | 
			
		||||
        <td valign="top" colspan="5" width="85%"
 | 
			
		||||
        bgcolor="#008080"><p align="center">Call_traits type:</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#008080"><p
 | 
			
		||||
        align="center">Original type T</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">value_type</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">reference</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">const_reference</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">param_type</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">Applies to:</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">myclass</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">myclass</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">myclass&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        myclass&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">myclass
 | 
			
		||||
        const&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">All user
 | 
			
		||||
        defined types.</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">int</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int const</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">All small
 | 
			
		||||
        built-in types.</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">int*</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int*</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int*&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int*const&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int* const</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">All
 | 
			
		||||
        pointer types.</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">All
 | 
			
		||||
        reference types.</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">const int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const
 | 
			
		||||
        int&</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">All
 | 
			
		||||
        constant-references.</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">int[3]</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const int*</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">int(&)[3]</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const int(&)[3]</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const int*
 | 
			
		||||
        const</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">All array
 | 
			
		||||
        types.</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td valign="top" width="17%" bgcolor="#C0C0C0"><p
 | 
			
		||||
        align="center">const int[3]</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const int*</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const int(&)[3]</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const int(&)[3]</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">const int*
 | 
			
		||||
        const</p>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td valign="top" width="17%"><p align="center">All
 | 
			
		||||
        constant-array types.</p>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<p> </p>
 | 
			
		||||
 | 
			
		||||
<h4>Example 1:</h4>
 | 
			
		||||
 | 
			
		||||
<p>The following class is a trivial class that stores some type T
 | 
			
		||||
by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
 | 
			
		||||
file), the aim is to illustrate how each of the available
 | 
			
		||||
call_traits typedefs may be used:</p>
 | 
			
		||||
 | 
			
		||||
<pre>template <class T>
 | 
			
		||||
struct contained
 | 
			
		||||
{
 | 
			
		||||
   // define our typedefs first, arrays are stored by value
 | 
			
		||||
   // so value_type is not the same as result_type:
 | 
			
		||||
   typedef typename boost::call_traits<T>::param_type       param_type;
 | 
			
		||||
   typedef typename boost::call_traits<T>::reference        reference;
 | 
			
		||||
   typedef typename boost::call_traits<T>::const_reference  const_reference;
 | 
			
		||||
   typedef T                                                value_type;
 | 
			
		||||
   typedef typename boost::call_traits<T>::value_type       result_type;
 | 
			
		||||
 | 
			
		||||
   // stored value:
 | 
			
		||||
   value_type v_;
 | 
			
		||||
   
 | 
			
		||||
   // constructors:
 | 
			
		||||
   contained() {}
 | 
			
		||||
   contained(param_type p) : v_(p){}
 | 
			
		||||
   // return byval:
 | 
			
		||||
   result_type value() { return v_; }
 | 
			
		||||
   // return by_ref:
 | 
			
		||||
   reference get() { return v_; }
 | 
			
		||||
   const_reference const_get()const { return v_; }
 | 
			
		||||
   // pass value:
 | 
			
		||||
   void call(param_type p){}
 | 
			
		||||
 | 
			
		||||
};</pre>
 | 
			
		||||
 | 
			
		||||
<h4><a name="refs"></a>Example 2 (the reference to reference
 | 
			
		||||
problem):</h4>
 | 
			
		||||
 | 
			
		||||
<p>Consider the definition of std::binder1st:</p>
 | 
			
		||||
 | 
			
		||||
<pre>template <class Operation> 
 | 
			
		||||
class binder1st : 
 | 
			
		||||
   public unary_function<typename Operation::second_argument_type, typename Operation::result_type> 
 | 
			
		||||
{ 
 | 
			
		||||
protected: 
 | 
			
		||||
   Operation op; 
 | 
			
		||||
   typename Operation::first_argument_type value; 
 | 
			
		||||
public: 
 | 
			
		||||
   binder1st(const Operation& x, const typename Operation::first_argument_type& y); 
 | 
			
		||||
   typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const; 
 | 
			
		||||
}; </pre>
 | 
			
		||||
 | 
			
		||||
<p>Now consider what happens in the relatively common case that
 | 
			
		||||
the functor takes its second argument as a reference, that
 | 
			
		||||
implies that <code>Operation::second_argument_type</code> is a
 | 
			
		||||
reference type, <code>operator()</code> will now end up taking a
 | 
			
		||||
reference to a reference as an argument, and that is not
 | 
			
		||||
currently legal. The solution here is to modify <code>operator()</code>
 | 
			
		||||
to use call_traits:</p>
 | 
			
		||||
 | 
			
		||||
<pre>typename Operation::result_type operator()(typename call_traits<typename Operation::second_argument_type>::param_type x) const;</pre>
 | 
			
		||||
 | 
			
		||||
<p>Now in the case that <code>Operation::second_argument_type</code>
 | 
			
		||||
is a reference type, the argument is passed as a reference, and
 | 
			
		||||
the no "reference to reference" occurs.</p>
 | 
			
		||||
 | 
			
		||||
<h4><a name="ex3"></a>Example 3 (the make_pair problem):</h4>
 | 
			
		||||
 | 
			
		||||
<p>If we pass the name of an array as one (or both) arguments to <code>std::make_pair</code>,
 | 
			
		||||
then template argument deduction deduces the passed parameter as
 | 
			
		||||
"const reference to array of T", this also applies to
 | 
			
		||||
string literals (which are really array literals). Consequently
 | 
			
		||||
instead of returning a pair of pointers, it tries to return a
 | 
			
		||||
pair of arrays, and since an array type is not copy-constructible
 | 
			
		||||
the code fails to compile. One solution is to explicitly cast the
 | 
			
		||||
arguments to make_pair to pointers, but call_traits provides a
 | 
			
		||||
better (i.e. automatic) solution (and one that works safely even
 | 
			
		||||
in generic code where the cast might do the wrong thing):</p>
 | 
			
		||||
 | 
			
		||||
<pre>template <class T1, class T2>
 | 
			
		||||
std::pair<
 | 
			
		||||
   typename boost::call_traits<T1>::value_type, 
 | 
			
		||||
   typename boost::call_traits<T2>::value_type> 
 | 
			
		||||
      make_pair(const T1& t1, const T2& t2)
 | 
			
		||||
{
 | 
			
		||||
   return std::pair<
 | 
			
		||||
      typename boost::call_traits<T1>::value_type, 
 | 
			
		||||
      typename boost::call_traits<T2>::value_type>(t1, t2);
 | 
			
		||||
}</pre>
 | 
			
		||||
 | 
			
		||||
<p>Here, the deduced argument types will be automatically
 | 
			
		||||
degraded to pointers if the deduced types are arrays, similar
 | 
			
		||||
situations occur in the standard binders and adapters: in
 | 
			
		||||
principle in any function that "wraps" a temporary
 | 
			
		||||
whose type is deduced. Note that the function arguments to
 | 
			
		||||
make_pair are not expressed in terms of call_traits: doing so
 | 
			
		||||
would prevent template argument deduction from functioning.</p>
 | 
			
		||||
 | 
			
		||||
<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
 | 
			
		||||
 | 
			
		||||
<p>The call_traits template will "optimize" the passing
 | 
			
		||||
of a small built-in type as a function parameter, this mainly has
 | 
			
		||||
an effect when the parameter is used within a loop body. In the
 | 
			
		||||
following example (see <a
 | 
			
		||||
href="../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
 | 
			
		||||
used, but with the passed parameter "optimized" using
 | 
			
		||||
call_traits:</p>
 | 
			
		||||
 | 
			
		||||
<pre>namespace detail{
 | 
			
		||||
 | 
			
		||||
template <bool opt>
 | 
			
		||||
struct filler
 | 
			
		||||
{
 | 
			
		||||
   template <typename I, typename T>
 | 
			
		||||
   static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val)
 | 
			
		||||
   {
 | 
			
		||||
      while(first != last)
 | 
			
		||||
      {
 | 
			
		||||
         *first = val;
 | 
			
		||||
         ++first;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct filler<true>
 | 
			
		||||
{
 | 
			
		||||
   template <typename I, typename T>
 | 
			
		||||
   static void do_fill(I first, I last, T val)
 | 
			
		||||
   {
 | 
			
		||||
      memset(first, val, last-first);
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class I, class T>
 | 
			
		||||
inline void fill(I first, I last, const T& val)
 | 
			
		||||
{
 | 
			
		||||
   enum{ can_opt = boost::is_pointer<I>::value
 | 
			
		||||
                   && boost::is_arithmetic<T>::value
 | 
			
		||||
                   && (sizeof(T) == 1) };
 | 
			
		||||
   typedef detail::filler<can_opt> filler_t;
 | 
			
		||||
   filler_t::template do_fill<I,T>(first, last, val);
 | 
			
		||||
}</pre>
 | 
			
		||||
 | 
			
		||||
<p>Footnote: the reason that this is "optimal" for
 | 
			
		||||
small built-in types is that with the value passed as "T
 | 
			
		||||
const" instead of "const T&" the compiler is
 | 
			
		||||
able to tell both that the value is constant and that it is free
 | 
			
		||||
of aliases. With this information the compiler is able to cache
 | 
			
		||||
the passed value in a register, unroll the loop, or use
 | 
			
		||||
explicitly parallel instructions: if any of these are supported.
 | 
			
		||||
Exactly how much mileage you will get from this depends upon your
 | 
			
		||||
compiler - we could really use some accurate benchmarking
 | 
			
		||||
software as part of boost for cases like this.</p>
 | 
			
		||||
 | 
			
		||||
<p>Note that the function arguments to fill are not expressed in
 | 
			
		||||
terms of call_traits: doing so would prevent template argument
 | 
			
		||||
deduction from functioning. Instead fill acts as a "thin
 | 
			
		||||
wrapper" that is there to perform template argument
 | 
			
		||||
deduction, the compiler will optimise away the call to fill all
 | 
			
		||||
together, replacing it with the call to filler<>::do_fill,
 | 
			
		||||
which does use call_traits.</p>
 | 
			
		||||
 | 
			
		||||
<h3>Rationale</h3>
 | 
			
		||||
 | 
			
		||||
<p>The following notes are intended to briefly describe the
 | 
			
		||||
rational behind choices made in call_traits.</p>
 | 
			
		||||
 | 
			
		||||
<p>All user-defined types follow "existing practice"
 | 
			
		||||
and need no comment.</p>
 | 
			
		||||
 | 
			
		||||
<p>Small built-in types (what the standard calls fundamental
 | 
			
		||||
types [3.9.1]) differ from existing practice only in the <i>param_type</i>
 | 
			
		||||
typedef. In this case passing "T const" is compatible
 | 
			
		||||
with existing practice, but may improve performance in some cases
 | 
			
		||||
(see <a href="#ex4">Example 4</a>), in any case this should never
 | 
			
		||||
be any worse than existing practice.</p>
 | 
			
		||||
 | 
			
		||||
<p>Pointers follow the same rational as small built-in types.</p>
 | 
			
		||||
 | 
			
		||||
<p>For reference types the rational follows <a href="#refs">Example
 | 
			
		||||
2</a> - references to references are not allowed, so the
 | 
			
		||||
call_traits members must be defined such that these problems do
 | 
			
		||||
not occur. There is a proposal to modify the language such that
 | 
			
		||||
"a reference to a reference is a reference" (issue #106,
 | 
			
		||||
submitted by Bjarne Stroustrup), call_traits<T>::value_type
 | 
			
		||||
and call_traits<T>::param_type both provide the same effect
 | 
			
		||||
as that proposal, without the need for a language change (in
 | 
			
		||||
other words it's a workaround).</p>
 | 
			
		||||
 | 
			
		||||
<p>For array types, a function that takes an array as an argument
 | 
			
		||||
will degrade the array type to a pointer type: this means that
 | 
			
		||||
the type of the actual parameter is different from its declared
 | 
			
		||||
type, something that can cause endless problems in template code
 | 
			
		||||
that relies on the declared type of a parameter. For example:</p>
 | 
			
		||||
 | 
			
		||||
<pre>template <class T>
 | 
			
		||||
struct A
 | 
			
		||||
{
 | 
			
		||||
   void foo(T t);
 | 
			
		||||
};</pre>
 | 
			
		||||
 | 
			
		||||
<p><font face="Times New Roman">In this case if we instantiate
 | 
			
		||||
A<int[2]> then the declared type of the parameter passed to
 | 
			
		||||
member function foo is int[2], but it's actual type is const int*,
 | 
			
		||||
if we try to use the type T within the function body, then there
 | 
			
		||||
is a strong likelyhood that our code will not compile:</font></p>
 | 
			
		||||
 | 
			
		||||
<pre>template <class T>
 | 
			
		||||
void A<T>::foo(T t)
 | 
			
		||||
{
 | 
			
		||||
   T dup(t); // doesn't compile for case that T is an array.
 | 
			
		||||
}</pre>
 | 
			
		||||
 | 
			
		||||
<p>By using call_traits the degradation from array to pointer is
 | 
			
		||||
explicit, and the type of the parameter is the same as it's
 | 
			
		||||
declared type:</p>
 | 
			
		||||
 | 
			
		||||
<pre>template <class T>
 | 
			
		||||
struct A
 | 
			
		||||
{
 | 
			
		||||
   void foo(typename call_traits<T>::value_type t);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void A<T>::foo(typename call_traits<T>::value_type t)
 | 
			
		||||
{
 | 
			
		||||
   typename call_traits<T>::value_type dup(t); // OK even if T is an array type.
 | 
			
		||||
}</pre>
 | 
			
		||||
 | 
			
		||||
<p>For value_type (return by value), again only a pointer may be
 | 
			
		||||
returned, not a copy of the whole array, and again call_traits
 | 
			
		||||
makes the degradation explicit. The value_type member is useful
 | 
			
		||||
whenever an array must be explicitly degraded to a pointer - <a
 | 
			
		||||
href="#ex3">Example 3</a> provides the test case (Footnote: the
 | 
			
		||||
array specialisation for call_traits is the least well understood
 | 
			
		||||
of all the call_traits specialisations, if the given semantics
 | 
			
		||||
cause specific problems for you, or don't solve a particular
 | 
			
		||||
array-related problem, then I would be interested to hear about
 | 
			
		||||
it. Most people though will probably never need to use this
 | 
			
		||||
specialisation).</p>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<p>Revised 01 September 2000</p>
 | 
			
		||||
 | 
			
		||||
   <p>
 | 
			
		||||
      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>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										405
									
								
								call_traits_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								call_traits_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,405 @@
 | 
			
		||||
//  boost::compressed_pair test program   
 | 
			
		||||
    
 | 
			
		||||
//  (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 <iostream>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/call_traits.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:
 | 
			
		||||
//
 | 
			
		||||
template <class T>
 | 
			
		||||
struct contained
 | 
			
		||||
{
 | 
			
		||||
   // define our typedefs first, arrays are stored by value
 | 
			
		||||
   // so value_type is not the same as result_type:
 | 
			
		||||
   typedef typename boost::call_traits<T>::param_type       param_type;
 | 
			
		||||
   typedef typename boost::call_traits<T>::reference        reference;
 | 
			
		||||
   typedef typename boost::call_traits<T>::const_reference  const_reference;
 | 
			
		||||
   typedef T                                                value_type;
 | 
			
		||||
   typedef typename boost::call_traits<T>::value_type       result_type;
 | 
			
		||||
 | 
			
		||||
   // stored value:
 | 
			
		||||
   value_type v_;
 | 
			
		||||
   
 | 
			
		||||
   // constructors:
 | 
			
		||||
   contained() {}
 | 
			
		||||
   contained(param_type p) : v_(p){}
 | 
			
		||||
   // return byval:
 | 
			
		||||
   result_type value()const { return v_; }
 | 
			
		||||
   // return by_ref:
 | 
			
		||||
   reference get() { return v_; }
 | 
			
		||||
   const_reference const_get()const { return v_; }
 | 
			
		||||
   // pass value:
 | 
			
		||||
   void call(param_type){}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
template <class T, std::size_t N>
 | 
			
		||||
struct contained<T[N]>
 | 
			
		||||
{
 | 
			
		||||
   typedef typename boost::call_traits<T[N]>::param_type       param_type;
 | 
			
		||||
   typedef typename boost::call_traits<T[N]>::reference        reference;
 | 
			
		||||
   typedef typename boost::call_traits<T[N]>::const_reference  const_reference;
 | 
			
		||||
   typedef T                                                   value_type[N];
 | 
			
		||||
   typedef typename boost::call_traits<T[N]>::value_type       result_type;
 | 
			
		||||
 | 
			
		||||
   value_type v_;
 | 
			
		||||
 | 
			
		||||
   contained(param_type p)
 | 
			
		||||
   {
 | 
			
		||||
      std::copy(p, p+N, v_);
 | 
			
		||||
   }
 | 
			
		||||
   // return byval:
 | 
			
		||||
   result_type value()const { return v_; }
 | 
			
		||||
   // return by_ref:
 | 
			
		||||
   reference get() { return v_; }
 | 
			
		||||
   const_reference const_get()const { return v_; }
 | 
			
		||||
   void call(param_type){}
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template <class 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace test{
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
std::pair<
 | 
			
		||||
   typename boost::call_traits<T1>::value_type,
 | 
			
		||||
   typename boost::call_traits<T2>::value_type>
 | 
			
		||||
      make_pair(const T1& t1, const T2& t2)
 | 
			
		||||
{
 | 
			
		||||
   return std::pair<
 | 
			
		||||
      typename boost::call_traits<T1>::value_type,
 | 
			
		||||
      typename boost::call_traits<T2>::value_type>(t1, t2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace test
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// struct call_traits_checker:
 | 
			
		||||
// verifies behaviour of contained example:
 | 
			
		||||
//
 | 
			
		||||
template <class T>
 | 
			
		||||
struct call_traits_checker
 | 
			
		||||
{
 | 
			
		||||
   typedef typename boost::call_traits<T>::param_type param_type;
 | 
			
		||||
   void operator()(param_type);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void call_traits_checker<T>::operator()(param_type p)
 | 
			
		||||
{
 | 
			
		||||
   T t(p);
 | 
			
		||||
   contained<T> c(t);
 | 
			
		||||
   cout << "checking contained<" << typeid(T).name() << ">..." << endl;
 | 
			
		||||
   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;
 | 
			
		||||
   cout << "typeof contained<" << typeid(T).name() << ">::get() is:        " << typeid(&contained<T>::get).name() << endl;
 | 
			
		||||
   cout << "typeof contained<" << typeid(T).name() << ">::const_get() is:  " << typeid(&contained<T>::const_get).name() << endl;
 | 
			
		||||
   cout << "typeof contained<" << typeid(T).name() << ">::call() is:       " << typeid(&contained<T>::call).name() << endl;
 | 
			
		||||
   cout << endl;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
template <class T, std::size_t N>
 | 
			
		||||
struct call_traits_checker<T[N]>
 | 
			
		||||
{
 | 
			
		||||
   typedef typename boost::call_traits<T[N]>::param_type param_type;
 | 
			
		||||
   void operator()(param_type t)
 | 
			
		||||
   {
 | 
			
		||||
      contained<T[N]> c(t);
 | 
			
		||||
      cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
 | 
			
		||||
      unsigned int i = 0;
 | 
			
		||||
      for(i = 0; i < N; ++i)
 | 
			
		||||
         BOOST_CHECK(t[i] == c.value()[i]);
 | 
			
		||||
      for(i = 0; i < N; ++i)
 | 
			
		||||
         BOOST_CHECK(t[i] == c.get()[i]);
 | 
			
		||||
      for(i = 0; i < N; ++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;
 | 
			
		||||
      cout << "typeof contained<" << typeid(T[N]).name() << ">::get is:        " << typeid(&contained<T[N]>::get).name() << endl;
 | 
			
		||||
      cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is:  " << typeid(&contained<T[N]>::const_get).name() << endl;
 | 
			
		||||
      cout << "typeof contained<" << typeid(T[N]).name() << ">::call is:       " << typeid(&contained<T[N]>::call).name() << endl;
 | 
			
		||||
      cout << endl;
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// check_wrap:
 | 
			
		||||
template <class W, class U>
 | 
			
		||||
void check_wrap(const W& w, const U& u)
 | 
			
		||||
{
 | 
			
		||||
   cout << "checking " << typeid(W).name() << "..." << endl;
 | 
			
		||||
   BOOST_CHECK(w.value() == u);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// check_make_pair:
 | 
			
		||||
// verifies behaviour of "make_pair":
 | 
			
		||||
//
 | 
			
		||||
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;
 | 
			
		||||
   BOOST_CHECK(c.first == u);
 | 
			
		||||
   BOOST_CHECK(c.second == v);
 | 
			
		||||
   cout << endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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_; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[ ])
 | 
			
		||||
{
 | 
			
		||||
   call_traits_checker<comparible_UDT> c1;
 | 
			
		||||
   comparible_UDT u;
 | 
			
		||||
   c1(u);
 | 
			
		||||
   call_traits_checker<int> c2;
 | 
			
		||||
   int i = 2;
 | 
			
		||||
   c2(i);
 | 
			
		||||
   int* pi = &i;
 | 
			
		||||
   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) && !defined(__MWERKS__) && !defined(__SUNPRO_CC)
 | 
			
		||||
   call_traits_checker<int[2]> c6;
 | 
			
		||||
   c6(a);
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   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
 | 
			
		||||
 | 
			
		||||
   // cv-qualifiers applied to reference types should have no effect
 | 
			
		||||
   // declare these here for later use with is_reference and remove_reference:
 | 
			
		||||
   typedef int& r_type;
 | 
			
		||||
   typedef const r_type cr_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;
 | 
			
		||||
#endif
 | 
			
		||||
   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
 | 
			
		||||
   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 specialiation, skipping 8 tests (8 errors)" << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
   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 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// define call_traits tests to check that the assertions in the docs do actually work
 | 
			
		||||
// this is an compile-time only set of tests:
 | 
			
		||||
//
 | 
			
		||||
template <typename T, bool isarray = false>
 | 
			
		||||
struct call_traits_test
 | 
			
		||||
{
 | 
			
		||||
   typedef ::boost::call_traits<T> ct;
 | 
			
		||||
   typedef typename ct::param_type param_type;
 | 
			
		||||
   typedef typename ct::reference reference;
 | 
			
		||||
   typedef typename ct::const_reference const_reference;
 | 
			
		||||
   typedef typename ct::value_type value_type;
 | 
			
		||||
   static void assert_construct(param_type val);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, bool isarray>
 | 
			
		||||
void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, isarray>::param_type val)
 | 
			
		||||
{
 | 
			
		||||
   //
 | 
			
		||||
   // this is to check that the call_traits assertions are valid:
 | 
			
		||||
   T t(val);
 | 
			
		||||
   value_type v(t);
 | 
			
		||||
   reference r(t);
 | 
			
		||||
   const_reference cr(t);
 | 
			
		||||
   param_type p(t);
 | 
			
		||||
   value_type v2(v);
 | 
			
		||||
   value_type v3(r);
 | 
			
		||||
   value_type v4(p);
 | 
			
		||||
   reference r2(v);
 | 
			
		||||
   reference r3(r);
 | 
			
		||||
   const_reference cr2(v);
 | 
			
		||||
   const_reference cr3(r);
 | 
			
		||||
   const_reference cr4(cr);
 | 
			
		||||
   const_reference cr5(p);
 | 
			
		||||
   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>
 | 
			
		||||
struct call_traits_test<T, true>
 | 
			
		||||
{
 | 
			
		||||
   typedef ::boost::call_traits<T> ct;
 | 
			
		||||
   typedef typename ct::param_type param_type;
 | 
			
		||||
   typedef typename ct::reference reference;
 | 
			
		||||
   typedef typename ct::const_reference const_reference;
 | 
			
		||||
   typedef typename ct::value_type value_type;
 | 
			
		||||
   static void assert_construct(param_type val);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val)
 | 
			
		||||
{
 | 
			
		||||
   //
 | 
			
		||||
   // this is to check that the call_traits assertions are valid:
 | 
			
		||||
   T t;
 | 
			
		||||
   value_type v(t);
 | 
			
		||||
   value_type v5(val);
 | 
			
		||||
   reference r = t;
 | 
			
		||||
   const_reference cr = t;
 | 
			
		||||
   reference r2 = r;
 | 
			
		||||
   #ifndef __BORLANDC__
 | 
			
		||||
   // C++ Builder buglet:
 | 
			
		||||
   const_reference cr2 = r;
 | 
			
		||||
   #endif
 | 
			
		||||
   param_type p(t);
 | 
			
		||||
   value_type v2(v);
 | 
			
		||||
   const_reference cr3 = cr;
 | 
			
		||||
   value_type v3(r);
 | 
			
		||||
   value_type v4(p);
 | 
			
		||||
   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
 | 
			
		||||
//
 | 
			
		||||
// now check call_traits assertions by instantiating call_traits_test:
 | 
			
		||||
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)
 | 
			
		||||
template struct call_traits_test<int&>;
 | 
			
		||||
template struct call_traits_test<const int&>;
 | 
			
		||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
 | 
			
		||||
template struct call_traits_test<int[2], true>;
 | 
			
		||||
#endif
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										76
									
								
								compressed_pair.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								compressed_pair.htm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
<html>
 | 
			
		||||
   <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:
 | 
			
		||||
	typedef T1                                                 first_type;
 | 
			
		||||
	typedef T2                                                 second_type;
 | 
			
		||||
	typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
	typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
	typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
	typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
	typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
	typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
	         compressed_pair() : base() {}
 | 
			
		||||
	         compressed_pair(first_param_type x, second_param_type y);
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
	second_reference       second();
 | 
			
		||||
	second_const_reference second() const;
 | 
			
		||||
 | 
			
		||||
	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>
 | 
			
		||||
 | 
			
		||||
   </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										395
									
								
								compressed_pair_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								compressed_pair_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,395 @@
 | 
			
		||||
//  boost::compressed_pair test program   
 | 
			
		||||
    
 | 
			
		||||
//  (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: 
 | 
			
		||||
//    Enabled tests for VC6.
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include <boost/compressed_pair.hpp>
 | 
			
		||||
#include <boost/test/test_tools.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace boost;
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
{ 
 | 
			
		||||
   int i;
 | 
			
		||||
   non_empty1() : i(1){}
 | 
			
		||||
   non_empty1(int v) : i(v){}
 | 
			
		||||
   friend bool operator==(const non_empty1& a, const non_empty1& b)
 | 
			
		||||
   { return a.i == b.i; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct non_empty2
 | 
			
		||||
{ 
 | 
			
		||||
   int i;
 | 
			
		||||
   non_empty2() : i(3){}
 | 
			
		||||
   non_empty2(int v) : i(v){}
 | 
			
		||||
   friend bool operator==(const non_empty2& a, const non_empty2& b)
 | 
			
		||||
   { return a.i == b.i; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
using std::swap;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// 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
 | 
			
		||||
   // first param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp2(p1);
 | 
			
		||||
   cp2.second() = p2;
 | 
			
		||||
   BOOST_CHECK(cp2.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp2.second() == p2);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
//
 | 
			
		||||
// supplimentary tests for case where second arg only is a reference type:
 | 
			
		||||
//
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// 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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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 J<>rvi (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 J<>rvi (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 J<>rvi (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 J<>rvi (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 J<>rvi (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 J<>rvi (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 J<>rvi (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 J<>rvi (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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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>
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										24
									
								
								include/boost/call_traits.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/boost/call_traits.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp
 | 
			
		||||
//  for full copyright notices.
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_CALL_TRAITS_HPP
 | 
			
		||||
#define BOOST_CALL_TRAITS_HPP
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_CONFIG_HPP
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
#include <boost/detail/ob_call_traits.hpp>
 | 
			
		||||
#else
 | 
			
		||||
#include <boost/detail/call_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_CALL_TRAITS_HPP
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										24
									
								
								include/boost/compressed_pair.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/boost/compressed_pair.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp
 | 
			
		||||
//  for full copyright notices.
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_COMPRESSED_PAIR_HPP
 | 
			
		||||
#define BOOST_COMPRESSED_PAIR_HPP
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_CONFIG_HPP
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
#include <boost/detail/ob_compressed_pair.hpp>
 | 
			
		||||
#else
 | 
			
		||||
#include <boost/detail/compressed_pair.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_COMPRESSED_PAIR_HPP
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										164
									
								
								include/boost/detail/call_traits.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								include/boost/detail/call_traits.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
// call_traits: defines typedefs for function usage
 | 
			
		||||
// (see libs/utility/call_traits.htm)
 | 
			
		||||
 | 
			
		||||
/* Release notes:
 | 
			
		||||
   23rd July 2000:
 | 
			
		||||
      Fixed array specialization. (JM)
 | 
			
		||||
      Added Borland specific fixes for reference types
 | 
			
		||||
      (issue raised by Steve Cleary).
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_DETAIL_CALL_TRAITS_HPP
 | 
			
		||||
#define BOOST_DETAIL_CALL_TRAITS_HPP
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_CONFIG_HPP
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
#include <boost/type_traits/is_arithmetic.hpp>
 | 
			
		||||
#include <boost/type_traits/is_pointer.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost{
 | 
			
		||||
 | 
			
		||||
namespace detail{
 | 
			
		||||
 | 
			
		||||
template <typename T, bool small_>
 | 
			
		||||
struct ct_imp2
 | 
			
		||||
{
 | 
			
		||||
   typedef const T& param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct ct_imp2<T, true>
 | 
			
		||||
{
 | 
			
		||||
   typedef const T param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, bool isp, bool b1>
 | 
			
		||||
struct ct_imp
 | 
			
		||||
{
 | 
			
		||||
   typedef const T& param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, bool isp>
 | 
			
		||||
struct ct_imp<T, isp, true>
 | 
			
		||||
{
 | 
			
		||||
   typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, bool b1>
 | 
			
		||||
struct ct_imp<T, true, b1>
 | 
			
		||||
{
 | 
			
		||||
   typedef const T param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_traits
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
   typedef T value_type;
 | 
			
		||||
   typedef T& reference;
 | 
			
		||||
   typedef const T& const_reference;
 | 
			
		||||
   //
 | 
			
		||||
   // C++ Builder workaround: we should be able to define a compile time
 | 
			
		||||
   // constant and pass that as a single template parameter to ct_imp<T,bool>,
 | 
			
		||||
   // however compiler bugs prevent this - instead pass three bool's to
 | 
			
		||||
   // ct_imp<T,bool,bool,bool> and add an extra partial specialisation
 | 
			
		||||
   // of ct_imp to handle the logic. (JM)
 | 
			
		||||
   typedef typename boost::detail::ct_imp<
 | 
			
		||||
      T,
 | 
			
		||||
      ::boost::is_pointer<T>::value,
 | 
			
		||||
      ::boost::is_arithmetic<T>::value
 | 
			
		||||
   >::param_type param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_traits<T&>
 | 
			
		||||
{
 | 
			
		||||
   typedef T& value_type;
 | 
			
		||||
   typedef T& reference;
 | 
			
		||||
   typedef const T& const_reference;
 | 
			
		||||
   typedef T& param_type;  // hh removed const
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if BOOST_WORKAROUND( __BORLANDC__,  BOOST_TESTED_AT( 0x581 ) )
 | 
			
		||||
// these are illegal specialisations; cv-qualifies applied to
 | 
			
		||||
// references have no effect according to [8.3.2p1],
 | 
			
		||||
// C++ Builder requires them though as it treats cv-qualified
 | 
			
		||||
// references as distinct types...
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_traits<T&const>
 | 
			
		||||
{
 | 
			
		||||
   typedef T& value_type;
 | 
			
		||||
   typedef T& reference;
 | 
			
		||||
   typedef const T& const_reference;
 | 
			
		||||
   typedef T& param_type;  // hh removed const
 | 
			
		||||
};
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_traits<T&volatile>
 | 
			
		||||
{
 | 
			
		||||
   typedef T& value_type;
 | 
			
		||||
   typedef T& reference;
 | 
			
		||||
   typedef const T& const_reference;
 | 
			
		||||
   typedef T& param_type;  // hh removed const
 | 
			
		||||
};
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_traits<T&const volatile>
 | 
			
		||||
{
 | 
			
		||||
   typedef T& value_type;
 | 
			
		||||
   typedef T& reference;
 | 
			
		||||
   typedef const T& const_reference;
 | 
			
		||||
   typedef T& param_type;  // hh removed const
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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]>
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   typedef T array_type[N];
 | 
			
		||||
public:
 | 
			
		||||
   // degrades array to pointer:
 | 
			
		||||
   typedef const T* value_type;
 | 
			
		||||
   typedef array_type& reference;
 | 
			
		||||
   typedef const array_type& const_reference;
 | 
			
		||||
   typedef const T* const param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, std::size_t N>
 | 
			
		||||
struct call_traits<const T [N]>
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   typedef const T array_type[N];
 | 
			
		||||
public:
 | 
			
		||||
   // degrades array to pointer:
 | 
			
		||||
   typedef const T* value_type;
 | 
			
		||||
   typedef array_type& reference;
 | 
			
		||||
   typedef const array_type& const_reference;
 | 
			
		||||
   typedef const T* const param_type;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_DETAIL_CALL_TRAITS_HPP
 | 
			
		||||
							
								
								
									
										443
									
								
								include/boost/detail/compressed_pair.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										443
									
								
								include/boost/detail/compressed_pair.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,443 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
// compressed_pair: pair that "compresses" empty members
 | 
			
		||||
// (see libs/utility/compressed_pair.htm)
 | 
			
		||||
//
 | 
			
		||||
// JM changes 25 Jan 2004:
 | 
			
		||||
// For the case where T1 == T2 and both are empty, then first() and second()
 | 
			
		||||
// should return different objects.
 | 
			
		||||
// JM changes 25 Jan 2000:
 | 
			
		||||
// Removed default arguments from compressed_pair_switch to get
 | 
			
		||||
// C++ Builder 4 to accept them
 | 
			
		||||
// rewriten swap to get gcc and C++ builder to compile.
 | 
			
		||||
// added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
 | 
			
		||||
#define BOOST_DETAIL_COMPRESSED_PAIR_HPP
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include <boost/type_traits/remove_cv.hpp>
 | 
			
		||||
#include <boost/type_traits/is_empty.hpp>
 | 
			
		||||
#include <boost/type_traits/is_same.hpp>
 | 
			
		||||
#include <boost/call_traits.hpp>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
{
 | 
			
		||||
   // JM altered 26 Jan 2000:
 | 
			
		||||
   template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
 | 
			
		||||
   struct compressed_pair_switch;
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct compressed_pair_switch<T1, T2, false, false, false>
 | 
			
		||||
      {static const int value = 0;};
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct compressed_pair_switch<T1, T2, false, true, true>
 | 
			
		||||
      {static const int value = 3;};
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct compressed_pair_switch<T1, T2, false, true, false>
 | 
			
		||||
      {static const int value = 1;};
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct compressed_pair_switch<T1, T2, false, false, true>
 | 
			
		||||
      {static const int value = 2;};
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct compressed_pair_switch<T1, T2, true, true, true>
 | 
			
		||||
      {static const int value = 4;};
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct compressed_pair_switch<T1, T2, true, false, false>
 | 
			
		||||
      {static const int value = 5;};
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2, int Version> class compressed_pair_imp;
 | 
			
		||||
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
   // workaround for GCC (JM):
 | 
			
		||||
   using std::swap;
 | 
			
		||||
#endif
 | 
			
		||||
   //
 | 
			
		||||
   // can't call unqualified swap from within classname::swap
 | 
			
		||||
   // as Koenig lookup rules will find only the classname::swap
 | 
			
		||||
   // member function not the global declaration, so use cp_swap
 | 
			
		||||
   // as a forwarding function (JM):
 | 
			
		||||
   template <typename T>
 | 
			
		||||
   inline void cp_swap(T& t1, T& t2)
 | 
			
		||||
   {
 | 
			
		||||
#ifndef __GNUC__
 | 
			
		||||
      using std::swap;
 | 
			
		||||
#endif
 | 
			
		||||
      swap(t1, t2);
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   // 0    derive from neither
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 0>
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
      typedef T2                                                 second_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
      typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
      typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp() {} 
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_(x), second_(y) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_(x) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(second_param_type y)
 | 
			
		||||
         : second_(y) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return first_;}
 | 
			
		||||
      first_const_reference first() const {return first_;}
 | 
			
		||||
 | 
			
		||||
      second_reference       second()       {return second_;}
 | 
			
		||||
      second_const_reference second() const {return second_;}
 | 
			
		||||
 | 
			
		||||
      void swap(::boost::compressed_pair<T1, T2>& y)
 | 
			
		||||
      {
 | 
			
		||||
         cp_swap(first_, y.first());
 | 
			
		||||
         cp_swap(second_, y.second());
 | 
			
		||||
      }
 | 
			
		||||
   private:
 | 
			
		||||
      first_type first_;
 | 
			
		||||
      second_type second_;
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   // 1    derive from T1
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 1>
 | 
			
		||||
      : protected ::boost::remove_cv<T1>::type
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
      typedef T2                                                 second_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
      typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
      typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp() {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_type(x), second_(y) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_type(x) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(second_param_type y)
 | 
			
		||||
         : second_(y) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return *this;}
 | 
			
		||||
      first_const_reference first() const {return *this;}
 | 
			
		||||
 | 
			
		||||
      second_reference       second()       {return second_;}
 | 
			
		||||
      second_const_reference second() const {return second_;}
 | 
			
		||||
 | 
			
		||||
      void swap(::boost::compressed_pair<T1,T2>& y)
 | 
			
		||||
      {
 | 
			
		||||
         // no need to swap empty base class:
 | 
			
		||||
         cp_swap(second_, y.second());
 | 
			
		||||
      }
 | 
			
		||||
   private:
 | 
			
		||||
      second_type second_;
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   // 2    derive from T2
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 2>
 | 
			
		||||
      : protected ::boost::remove_cv<T2>::type
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
      typedef T2                                                 second_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
      typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
      typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp() {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : second_type(y), first_(x) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_(x) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(second_param_type y)
 | 
			
		||||
         : second_type(y) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return first_;}
 | 
			
		||||
      first_const_reference first() const {return first_;}
 | 
			
		||||
 | 
			
		||||
      second_reference       second()       {return *this;}
 | 
			
		||||
      second_const_reference second() const {return *this;}
 | 
			
		||||
 | 
			
		||||
      void swap(::boost::compressed_pair<T1,T2>& y)
 | 
			
		||||
      {
 | 
			
		||||
         // no need to swap empty base class:
 | 
			
		||||
         cp_swap(first_, y.first());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
      first_type first_;
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   // 3    derive from T1 and T2
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 3>
 | 
			
		||||
      : protected ::boost::remove_cv<T1>::type,
 | 
			
		||||
        protected ::boost::remove_cv<T2>::type
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
      typedef T2                                                 second_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
      typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
      typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp() {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_type(x), second_type(y) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_type(x) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(second_param_type y)
 | 
			
		||||
         : second_type(y) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return *this;}
 | 
			
		||||
      first_const_reference first() const {return *this;}
 | 
			
		||||
 | 
			
		||||
      second_reference       second()       {return *this;}
 | 
			
		||||
      second_const_reference second() const {return *this;}
 | 
			
		||||
      //
 | 
			
		||||
      // no need to swap empty bases:
 | 
			
		||||
      void swap(::boost::compressed_pair<T1,T2>&) {}
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   // JM
 | 
			
		||||
   // 4    T1 == T2, T1 and T2 both empty
 | 
			
		||||
   //      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>
 | 
			
		||||
      : protected ::boost::remove_cv<T1>::type
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
      typedef T2                                                 second_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
      typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
      typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp() {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_type(x), m_second(y) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_type(x), m_second(x) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return *this;}
 | 
			
		||||
      first_const_reference first() const {return *this;}
 | 
			
		||||
 | 
			
		||||
      second_reference       second()       {return m_second;}
 | 
			
		||||
      second_const_reference second() const {return m_second;}
 | 
			
		||||
 | 
			
		||||
      void swap(::boost::compressed_pair<T1,T2>&) {}
 | 
			
		||||
   private:
 | 
			
		||||
      T2 m_second;
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   // 5    T1 == T2 and are not empty:   //JM
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 5>
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
      typedef T2                                                 second_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
      typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
      typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
      typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
      typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp() {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_(x), second_(y) {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_(x), second_(x) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return first_;}
 | 
			
		||||
      first_const_reference first() const {return first_;}
 | 
			
		||||
 | 
			
		||||
      second_reference       second()       {return second_;}
 | 
			
		||||
      second_const_reference second() const {return second_;}
 | 
			
		||||
 | 
			
		||||
      void swap(::boost::compressed_pair<T1, T2>& y)
 | 
			
		||||
      {
 | 
			
		||||
         cp_swap(first_, y.first());
 | 
			
		||||
         cp_swap(second_, y.second());
 | 
			
		||||
      }
 | 
			
		||||
   private:
 | 
			
		||||
      first_type first_;
 | 
			
		||||
      second_type second_;
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
}  // details
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair
 | 
			
		||||
   : private ::boost::details::compressed_pair_imp<T1, T2,
 | 
			
		||||
             ::boost::details::compressed_pair_switch<
 | 
			
		||||
                    T1,
 | 
			
		||||
                    T2,
 | 
			
		||||
                    ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
 | 
			
		||||
                    ::boost::is_empty<T1>::value,
 | 
			
		||||
                    ::boost::is_empty<T2>::value>::value>
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   typedef details::compressed_pair_imp<T1, T2,
 | 
			
		||||
             ::boost::details::compressed_pair_switch<
 | 
			
		||||
                    T1,
 | 
			
		||||
                    T2,
 | 
			
		||||
                    ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
 | 
			
		||||
                    ::boost::is_empty<T1>::value,
 | 
			
		||||
                    ::boost::is_empty<T2>::value>::value> base;
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair() : base() {}
 | 
			
		||||
            compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
 | 
			
		||||
   explicit compressed_pair(first_param_type x) : base(x) {}
 | 
			
		||||
   explicit compressed_pair(second_param_type y) : base(y) {}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       {return base::first();}
 | 
			
		||||
   first_const_reference first() const {return base::first();}
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       {return base::second();}
 | 
			
		||||
   second_const_reference second() const {return base::second();}
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair& y) { base::swap(y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// JM
 | 
			
		||||
// Partial specialisation for case where T1 == T2:
 | 
			
		||||
//
 | 
			
		||||
template <class T>
 | 
			
		||||
class compressed_pair<T, T>
 | 
			
		||||
   : private details::compressed_pair_imp<T, T,
 | 
			
		||||
             ::boost::details::compressed_pair_switch<
 | 
			
		||||
                    T,
 | 
			
		||||
                    T,
 | 
			
		||||
                    ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
 | 
			
		||||
                    ::boost::is_empty<T>::value,
 | 
			
		||||
                    ::boost::is_empty<T>::value>::value>
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   typedef details::compressed_pair_imp<T, T,
 | 
			
		||||
             ::boost::details::compressed_pair_switch<
 | 
			
		||||
                    T,
 | 
			
		||||
                    T,
 | 
			
		||||
                    ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
 | 
			
		||||
                    ::boost::is_empty<T>::value,
 | 
			
		||||
                    ::boost::is_empty<T>::value>::value> base;
 | 
			
		||||
public:
 | 
			
		||||
   typedef T                                                  first_type;
 | 
			
		||||
   typedef T                                                  second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair() : base() {}
 | 
			
		||||
            compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
 | 
			
		||||
#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
 | 
			
		||||
   explicit 
 | 
			
		||||
#endif
 | 
			
		||||
      compressed_pair(first_param_type x) : base(x) {}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       {return base::first();}
 | 
			
		||||
   first_const_reference first() const {return base::first();}
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       {return base::second();}
 | 
			
		||||
   second_const_reference second() const {return base::second();}
 | 
			
		||||
 | 
			
		||||
   void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
inline
 | 
			
		||||
void
 | 
			
		||||
swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
 | 
			
		||||
{
 | 
			
		||||
   x.swap(y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // boost
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif 
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										168
									
								
								include/boost/detail/ob_call_traits.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								include/boost/detail/ob_call_traits.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
//
 | 
			
		||||
//  Crippled version for crippled compilers:
 | 
			
		||||
//  see libs/utility/call_traits.htm
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
/* Release notes:
 | 
			
		||||
   01st October 2000:
 | 
			
		||||
      Fixed call_traits on VC6, using "poor man's partial specialisation",
 | 
			
		||||
      using ideas taken from "Generative programming" by Krzysztof Czarnecki 
 | 
			
		||||
      & Ulrich Eisenecker.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_OB_CALL_TRAITS_HPP
 | 
			
		||||
#define BOOST_OB_CALL_TRAITS_HPP
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_CONFIG_HPP
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
 | 
			
		||||
#include <boost/type_traits/arithmetic_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
 | 
			
		||||
#include <boost/type_traits/composite_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost{
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
 | 
			
		||||
//
 | 
			
		||||
// use member templates to emulate
 | 
			
		||||
// partial specialisation:
 | 
			
		||||
//
 | 
			
		||||
namespace detail{
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
struct standard_call_traits
 | 
			
		||||
{
 | 
			
		||||
   typedef T value_type;
 | 
			
		||||
   typedef T& reference;
 | 
			
		||||
   typedef const T& const_reference;
 | 
			
		||||
   typedef const T& param_type;
 | 
			
		||||
};
 | 
			
		||||
template <class T>
 | 
			
		||||
struct simple_call_traits
 | 
			
		||||
{
 | 
			
		||||
   typedef T value_type;
 | 
			
		||||
   typedef T& reference;
 | 
			
		||||
   typedef const T& const_reference;
 | 
			
		||||
   typedef const T param_type;
 | 
			
		||||
};
 | 
			
		||||
template <class T>
 | 
			
		||||
struct reference_call_traits
 | 
			
		||||
{
 | 
			
		||||
   typedef T value_type;
 | 
			
		||||
   typedef T reference;
 | 
			
		||||
   typedef T const_reference;
 | 
			
		||||
   typedef T param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <bool pointer, bool arithmetic, bool reference>
 | 
			
		||||
struct call_traits_chooser
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef standard_call_traits<T> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct call_traits_chooser<true, false, false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef simple_call_traits<T> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct call_traits_chooser<false, false, true>
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef reference_call_traits<T> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <bool size_is_small> 
 | 
			
		||||
struct call_traits_sizeof_chooser2
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct small_rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef simple_call_traits<T> small_type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> 
 | 
			
		||||
struct call_traits_sizeof_chooser2<false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct small_rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef standard_call_traits<T> small_type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct call_traits_chooser<false, true, false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) };
 | 
			
		||||
      typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser;
 | 
			
		||||
      typedef typename chooser::template small_rebind<T> bound_type;
 | 
			
		||||
      typedef typename bound_type::small_type type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_traits
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    typedef detail::call_traits_chooser<
 | 
			
		||||
         ::boost::is_pointer<T>::value,
 | 
			
		||||
         ::boost::is_arithmetic<T>::value, 
 | 
			
		||||
         ::boost::is_reference<T>::value
 | 
			
		||||
      > chooser;
 | 
			
		||||
   typedef typename chooser::template rebind<T> bound_type;
 | 
			
		||||
   typedef typename bound_type::type call_traits_type;
 | 
			
		||||
public:
 | 
			
		||||
   typedef typename call_traits_type::value_type       value_type;
 | 
			
		||||
   typedef typename call_traits_type::reference        reference;
 | 
			
		||||
   typedef typename call_traits_type::const_reference  const_reference;
 | 
			
		||||
   typedef typename call_traits_type::param_type       param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
//
 | 
			
		||||
// sorry call_traits is completely non-functional
 | 
			
		||||
// blame your broken compiler:
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_traits
 | 
			
		||||
{
 | 
			
		||||
   typedef T value_type;
 | 
			
		||||
   typedef T& reference;
 | 
			
		||||
   typedef const T& const_reference;
 | 
			
		||||
   typedef const T& param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // member templates
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_OB_CALL_TRAITS_HPP
 | 
			
		||||
							
								
								
									
										510
									
								
								include/boost/detail/ob_compressed_pair.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										510
									
								
								include/boost/detail/ob_compressed_pair.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,510 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
//  see libs/utility/compressed_pair.hpp
 | 
			
		||||
//
 | 
			
		||||
/* Release notes:
 | 
			
		||||
   20 Jan 2001:
 | 
			
		||||
        Fixed obvious bugs (David Abrahams)
 | 
			
		||||
   07 Oct 2000:
 | 
			
		||||
      Added better single argument constructor support.
 | 
			
		||||
   03 Oct 2000:
 | 
			
		||||
      Added VC6 support (JM).
 | 
			
		||||
   23rd July 2000:
 | 
			
		||||
      Additional comments added. (JM)
 | 
			
		||||
   Jan 2000:
 | 
			
		||||
      Original version: this version crippled for use with crippled compilers
 | 
			
		||||
      - John Maddock Jan 2000.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_OB_COMPRESSED_PAIR_HPP
 | 
			
		||||
#define BOOST_OB_COMPRESSED_PAIR_HPP
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
 | 
			
		||||
#include <boost/type_traits/object_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_SAME_TRAITS_HPP
 | 
			
		||||
#include <boost/type_traits/same_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_CALL_TRAITS_HPP
 | 
			
		||||
#include <boost/call_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
 | 
			
		||||
//
 | 
			
		||||
// use member templates to emulate
 | 
			
		||||
// partial specialisation.  Note that due to
 | 
			
		||||
// problems with overload resolution with VC6
 | 
			
		||||
// each of the compressed_pair versions that follow
 | 
			
		||||
// have one template single-argument constructor
 | 
			
		||||
// in place of two specific constructors:
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair;
 | 
			
		||||
 | 
			
		||||
namespace detail{
 | 
			
		||||
 | 
			
		||||
template <class A, class T1, class T2>
 | 
			
		||||
struct best_conversion_traits
 | 
			
		||||
{
 | 
			
		||||
   typedef char one;
 | 
			
		||||
   typedef char (&two)[2];
 | 
			
		||||
   static A a;
 | 
			
		||||
   static one test(T1);
 | 
			
		||||
   static two test(T2);
 | 
			
		||||
 | 
			
		||||
   enum { value = sizeof(test(a)) };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <int>
 | 
			
		||||
struct init_one;
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct init_one<1>
 | 
			
		||||
{
 | 
			
		||||
   template <class A, class T1, class T2>
 | 
			
		||||
   static void init(const A& a, T1* p1, T2*)
 | 
			
		||||
   {
 | 
			
		||||
      *p1 = a;
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct init_one<2>
 | 
			
		||||
{
 | 
			
		||||
   template <class A, class T1, class T2>
 | 
			
		||||
   static void init(const A& a, T1*, T2* p2)
 | 
			
		||||
   {
 | 
			
		||||
      *p2 = a;
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// T1 != T2, both non-empty
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair_0
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   T1 _first;
 | 
			
		||||
   T2 _second;
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair_0() : _first(), _second() {}
 | 
			
		||||
            compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
 | 
			
		||||
   template <class A>
 | 
			
		||||
   explicit compressed_pair_0(const A& val)
 | 
			
		||||
   {
 | 
			
		||||
      init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
 | 
			
		||||
   }
 | 
			
		||||
   compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
 | 
			
		||||
      : _first(x.first()), _second(x.second()) {}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  compressed_pair_0& operator=(const compressed_pair_0& x) {
 | 
			
		||||
    cout << "assigning compressed pair 0" << endl;
 | 
			
		||||
    _first = x._first;
 | 
			
		||||
    _second = x._second;
 | 
			
		||||
    cout << "finished assigning compressed pair 0" << endl;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       { return _first; }
 | 
			
		||||
   first_const_reference first() const { return _first; }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return _second; }
 | 
			
		||||
   second_const_reference second() const { return _second; }
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair_0& y)
 | 
			
		||||
   {
 | 
			
		||||
      using std::swap;
 | 
			
		||||
      swap(_first, y._first);
 | 
			
		||||
      swap(_second, y._second);
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// T1 != T2, T2 empty
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair_1 : T2
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   T1 _first;
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair_1() : T2(), _first() {}
 | 
			
		||||
            compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
 | 
			
		||||
 | 
			
		||||
   template <class A>
 | 
			
		||||
   explicit compressed_pair_1(const A& val)
 | 
			
		||||
   {
 | 
			
		||||
      init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
 | 
			
		||||
      : T2(x.second()), _first(x.first()) {}
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
 | 
			
		||||
  // Total weirdness. If the assignment to _first is moved after
 | 
			
		||||
  // the call to the inherited operator=, then this breaks graph/test/graph.cpp
 | 
			
		||||
  // by way of iterator_adaptor.
 | 
			
		||||
  compressed_pair_1& operator=(const compressed_pair_1& x) {
 | 
			
		||||
    _first = x._first;
 | 
			
		||||
    T2::operator=(x);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       { return _first; }
 | 
			
		||||
   first_const_reference first() const { return _first; }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return *this; }
 | 
			
		||||
   second_const_reference second() const { return *this; }
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair_1& y)
 | 
			
		||||
   {
 | 
			
		||||
      // no need to swap empty base class:
 | 
			
		||||
      using std::swap;
 | 
			
		||||
      swap(_first, y._first);
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// T1 != T2, T1 empty
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair_2 : T1
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   T2 _second;
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair_2() : T1(), _second() {}
 | 
			
		||||
            compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
 | 
			
		||||
   template <class A>
 | 
			
		||||
   explicit compressed_pair_2(const A& val)
 | 
			
		||||
   {
 | 
			
		||||
      init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
 | 
			
		||||
   }
 | 
			
		||||
   compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
 | 
			
		||||
      : T1(x.first()), _second(x.second()) {}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  compressed_pair_2& operator=(const compressed_pair_2& x) {
 | 
			
		||||
    cout << "assigning compressed pair 2" << endl;
 | 
			
		||||
    T1::operator=(x);
 | 
			
		||||
    _second = x._second;
 | 
			
		||||
    cout << "finished assigning compressed pair 2" << endl;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
   first_reference       first()       { return *this; }
 | 
			
		||||
   first_const_reference first() const { return *this; }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return _second; }
 | 
			
		||||
   second_const_reference second() const { return _second; }
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair_2& y)
 | 
			
		||||
   {
 | 
			
		||||
      // no need to swap empty base class:
 | 
			
		||||
      using std::swap;
 | 
			
		||||
      swap(_second, y._second);
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// T1 != T2, both empty
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair_3 : T1, T2
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair_3() : T1(), T2() {}
 | 
			
		||||
            compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
 | 
			
		||||
   template <class A>
 | 
			
		||||
   explicit compressed_pair_3(const A& val)
 | 
			
		||||
   {
 | 
			
		||||
      init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
 | 
			
		||||
   }
 | 
			
		||||
   compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
 | 
			
		||||
      : T1(x.first()), T2(x.second()) {}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       { return *this; }
 | 
			
		||||
   first_const_reference first() const { return *this; }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return *this; }
 | 
			
		||||
   second_const_reference second() const { return *this; }
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair_3& y)
 | 
			
		||||
   {
 | 
			
		||||
      // no need to swap empty base classes:
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// T1 == T2, and empty
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair_4 : T1
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair_4() : T1() {}
 | 
			
		||||
            compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
 | 
			
		||||
   // only one single argument constructor since T1 == T2
 | 
			
		||||
   explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
 | 
			
		||||
   compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
 | 
			
		||||
      : T1(x.first()), m_second(x.second()) {}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       { return *this; }
 | 
			
		||||
   first_const_reference first() const { return *this; }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return m_second; }
 | 
			
		||||
   second_const_reference second() const { return m_second; }
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair_4& y)
 | 
			
		||||
   {
 | 
			
		||||
      // no need to swap empty base classes:
 | 
			
		||||
   }
 | 
			
		||||
private:
 | 
			
		||||
   T2 m_second;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// T1 == T2, not empty
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair_5
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   T1 _first;
 | 
			
		||||
   T2 _second;
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair_5() : _first(), _second() {}
 | 
			
		||||
            compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
 | 
			
		||||
   // only one single argument constructor since T1 == T2
 | 
			
		||||
   explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
 | 
			
		||||
   compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c) 
 | 
			
		||||
      : _first(c.first()), _second(c.second()) {}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       { return _first; }
 | 
			
		||||
   first_const_reference first() const { return _first; }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return _second; }
 | 
			
		||||
   second_const_reference second() const { return _second; }
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair_5& y)
 | 
			
		||||
   {
 | 
			
		||||
      using std::swap;
 | 
			
		||||
      swap(_first, y._first);
 | 
			
		||||
      swap(_second, y._second);
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <bool e1, bool e2, bool same>
 | 
			
		||||
struct compressed_pair_chooser
 | 
			
		||||
{
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef compressed_pair_0<T1, T2> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct compressed_pair_chooser<false, true, false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef compressed_pair_1<T1, T2> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct compressed_pair_chooser<true, false, false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef compressed_pair_2<T1, T2> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct compressed_pair_chooser<true, true, false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef compressed_pair_3<T1, T2> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct compressed_pair_chooser<true, true, true>
 | 
			
		||||
{
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef compressed_pair_4<T1, T2> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct compressed_pair_chooser<false, false, true>
 | 
			
		||||
{
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef compressed_pair_5<T1, T2> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
struct compressed_pair_traits
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
 | 
			
		||||
   typedef typename chooser::template rebind<T1, T2> bound_type;
 | 
			
		||||
public:
 | 
			
		||||
   typedef typename bound_type::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair() : base_type() {}
 | 
			
		||||
            compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
 | 
			
		||||
   template <class A>
 | 
			
		||||
   explicit compressed_pair(const A& x) : base_type(x){}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       { return base_type::first(); }
 | 
			
		||||
   first_const_reference first() const { return base_type::first(); }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return base_type::second(); }
 | 
			
		||||
   second_const_reference second() const { return base_type::second(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
 | 
			
		||||
{
 | 
			
		||||
   x.swap(y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
// no partial specialisation, no member templates:
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   T1 _first;
 | 
			
		||||
   T2 _second;
 | 
			
		||||
public:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::reference        first_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::reference       second_reference;
 | 
			
		||||
   typedef typename call_traits<first_type>::const_reference  first_const_reference;
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair() : _first(), _second() {}
 | 
			
		||||
            compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
 | 
			
		||||
   explicit compressed_pair(first_param_type x) : _first(x), _second() {}
 | 
			
		||||
   // can't define this in case T1 == T2:
 | 
			
		||||
   // explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       { return _first; }
 | 
			
		||||
   first_const_reference first() const { return _first; }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return _second; }
 | 
			
		||||
   second_const_reference second() const { return _second; }
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair& y)
 | 
			
		||||
   {
 | 
			
		||||
      using std::swap;
 | 
			
		||||
      swap(_first, y._first);
 | 
			
		||||
      swap(_second, y._second);
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
 | 
			
		||||
{
 | 
			
		||||
   x.swap(y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // boost
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_OB_COMPRESSED_PAIR_HPP
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								include/boost/exception.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								include/boost/exception.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
//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/info_tuple.hpp>
 | 
			
		||||
#include <boost/exception/cloning.hpp>
 | 
			
		||||
#include <boost/throw_exception.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
 | 
			
		||||
							
								
								
									
										945
									
								
								include/boost/operators.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										945
									
								
								include/boost/operators.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,945 @@
 | 
			
		||||
//  Boost operators.hpp header file  ----------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-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/operators.htm for documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  03 Apr 08 Make sure "convertible to bool" is sufficient
 | 
			
		||||
//            for T::operator<, etc. (Daniel Frey)
 | 
			
		||||
//  24 May 07 Changed empty_base to depend on T, see
 | 
			
		||||
//            http://svn.boost.org/trac/boost/ticket/979
 | 
			
		||||
//  21 Oct 02 Modified implementation of operators to allow compilers with a
 | 
			
		||||
//            correct named return value optimization (NRVO) to produce optimal
 | 
			
		||||
//            code.  (Daniel Frey)
 | 
			
		||||
//  02 Dec 01 Bug fixed in random_access_iteratable.  (Helmut Zeisel)
 | 
			
		||||
//  28 Sep 01 Factored out iterator operator groups.  (Daryle Walker)
 | 
			
		||||
//  27 Aug 01 'left' form for non commutative operators added;
 | 
			
		||||
//            additional classes for groups of related operators added;
 | 
			
		||||
//            workaround for empty base class optimization
 | 
			
		||||
//            bug of GCC 3.0 (Helmut Zeisel)
 | 
			
		||||
//  25 Jun 01 output_iterator_helper changes: removed default template 
 | 
			
		||||
//            parameters, added support for self-proxying, additional 
 | 
			
		||||
//            documentation and tests (Aleksey Gurtovoy)
 | 
			
		||||
//  29 May 01 Added operator classes for << and >>.  Added input and output
 | 
			
		||||
//            iterator helper classes.  Added classes to connect equality and
 | 
			
		||||
//            relational operators.  Added classes for groups of related
 | 
			
		||||
//            operators.  Reimplemented example operator and iterator helper
 | 
			
		||||
//            classes in terms of the new groups.  (Daryle Walker, with help
 | 
			
		||||
//            from Alexy Gurtovoy)
 | 
			
		||||
//  11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
 | 
			
		||||
//            supplied arguments from actually being used (Dave Abrahams)
 | 
			
		||||
//  04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
 | 
			
		||||
//            refactoring of compiler workarounds, additional documentation
 | 
			
		||||
//            (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
 | 
			
		||||
//            Dave Abrahams) 
 | 
			
		||||
//  28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
 | 
			
		||||
//            Jeremy Siek (Dave Abrahams)
 | 
			
		||||
//  20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
 | 
			
		||||
//            (Mark Rodgers)
 | 
			
		||||
//  20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
 | 
			
		||||
//  10 Jun 00 Support for the base class chaining technique was added
 | 
			
		||||
//            (Aleksey Gurtovoy). See documentation and the comments below 
 | 
			
		||||
//            for the details. 
 | 
			
		||||
//  12 Dec 99 Initial version with iterator operators (Jeremy Siek)
 | 
			
		||||
//  18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
 | 
			
		||||
//            specializations of dividable, subtractable, modable (Ed Brey) 
 | 
			
		||||
//  17 Nov 99 Add comments (Beman Dawes)
 | 
			
		||||
//            Remove unnecessary specialization of operators<> (Ed Brey)
 | 
			
		||||
//  15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
 | 
			
		||||
//            operators.(Beman Dawes)
 | 
			
		||||
//  12 Nov 99 Add operators templates (Ed Brey)
 | 
			
		||||
//  11 Nov 99 Add single template parameter version for compilers without
 | 
			
		||||
//            partial specialization (Beman Dawes)
 | 
			
		||||
//  10 Nov 99 Initial version
 | 
			
		||||
 | 
			
		||||
// 10 Jun 00:
 | 
			
		||||
// An additional optional template parameter was added to most of 
 | 
			
		||||
// operator templates to support the base class chaining technique (see 
 | 
			
		||||
// documentation for the details). Unfortunately, a straightforward
 | 
			
		||||
// implementation of this change would have broken compatibility with the
 | 
			
		||||
// previous version of the library by making it impossible to use the same
 | 
			
		||||
// template name (e.g. 'addable') for both the 1- and 2-argument versions of
 | 
			
		||||
// an operator template. This implementation solves the backward-compatibility
 | 
			
		||||
// issue at the cost of some simplicity.
 | 
			
		||||
//
 | 
			
		||||
// One of the complications is an existence of special auxiliary class template
 | 
			
		||||
// 'is_chained_base<>' (see 'detail' namespace below), which is used
 | 
			
		||||
// to determine whether its template parameter is a library's operator template
 | 
			
		||||
// or not. You have to specialize 'is_chained_base<>' for each new 
 | 
			
		||||
// operator template you add to the library.
 | 
			
		||||
//
 | 
			
		||||
// However, most of the non-trivial implementation details are hidden behind 
 | 
			
		||||
// several local macros defined below, and as soon as you understand them,
 | 
			
		||||
// you understand the whole library implementation. 
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_OPERATORS_HPP
 | 
			
		||||
#define BOOST_OPERATORS_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/iterator.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(__sgi) && !defined(__GNUC__)
 | 
			
		||||
#   pragma set woff 1234
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC)
 | 
			
		||||
#   pragma warning( disable : 4284 ) // complaint about return type of 
 | 
			
		||||
#endif                               // operator-> not begin a UDT
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
template <typename T> class empty_base {
 | 
			
		||||
 | 
			
		||||
// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
 | 
			
		||||
#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
 | 
			
		||||
  bool dummy; 
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
// In this section we supply the xxxx1 and xxxx2 forms of the operator
 | 
			
		||||
// templates, which are explicitly targeted at the 1-type-argument and
 | 
			
		||||
// 2-type-argument operator forms, respectively. Some compilers get confused
 | 
			
		||||
// when inline friend functions are overloaded in namespaces other than the
 | 
			
		||||
// global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
 | 
			
		||||
// these templates must go in the global namespace.
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  Basic operator classes (contributed by Dave Abrahams) ------------------//
 | 
			
		||||
 | 
			
		||||
//  Note that friend functions defined in a class are implicitly inline.
 | 
			
		||||
//  See the C++ std, 11.4 [class.friend] paragraph 5
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct less_than_comparable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
 | 
			
		||||
     friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
 | 
			
		||||
     friend bool operator>(const U& x, const T& y)  { return y < x; }
 | 
			
		||||
     friend bool operator<(const U& x, const T& y)  { return y > x; }
 | 
			
		||||
     friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
 | 
			
		||||
     friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct less_than_comparable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend bool operator>(const T& x, const T& y)  { return y < x; }
 | 
			
		||||
     friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
 | 
			
		||||
     friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct equality_comparable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend bool operator==(const U& y, const T& x) { return x == y; }
 | 
			
		||||
     friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
 | 
			
		||||
     friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct equality_comparable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// A macro which produces "name_2left" from "name".
 | 
			
		||||
#define BOOST_OPERATOR2_LEFT(name) name##2##_##left
 | 
			
		||||
 | 
			
		||||
//  NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
// This is the optimal implementation for ISO/ANSI C++,
 | 
			
		||||
// but it requires the compiler to implement the NRVO.
 | 
			
		||||
// If the compiler has no NRVO, this is the best symmetric
 | 
			
		||||
// implementation available.
 | 
			
		||||
 | 
			
		||||
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                         \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >        \
 | 
			
		||||
struct NAME##2 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( const T& lhs, const U& rhs )                          \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 | 
			
		||||
  friend T operator OP( const U& lhs, const T& rhs )                          \
 | 
			
		||||
    { T nrv( rhs ); nrv OP##= lhs; return nrv; }                              \
 | 
			
		||||
};                                                                            \
 | 
			
		||||
                                                                              \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >                 \
 | 
			
		||||
struct NAME##1 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( const T& lhs, const T& rhs )                          \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
 | 
			
		||||
struct NAME##2 : B                                                      \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( const T& lhs, const U& rhs )                    \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
 | 
			
		||||
};                                                                      \
 | 
			
		||||
                                                                        \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
 | 
			
		||||
struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( const U& lhs, const T& rhs )                    \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
 | 
			
		||||
};                                                                      \
 | 
			
		||||
                                                                        \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >           \
 | 
			
		||||
struct NAME##1 : B                                                      \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( const T& lhs, const T& rhs )                    \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
// For compilers without NRVO the following code is optimal, but not
 | 
			
		||||
// symmetric!  Note that the implementation of
 | 
			
		||||
// BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
 | 
			
		||||
// optimization opportunities to the compiler :)
 | 
			
		||||
 | 
			
		||||
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                   \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
 | 
			
		||||
struct NAME##2 : B                                                      \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
 | 
			
		||||
  friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
 | 
			
		||||
};                                                                      \
 | 
			
		||||
                                                                        \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >           \
 | 
			
		||||
struct NAME##1 : B                                                      \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
 | 
			
		||||
struct NAME##2 : B                                                      \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
 | 
			
		||||
};                                                                      \
 | 
			
		||||
                                                                        \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >  \
 | 
			
		||||
struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( const U& lhs, const T& rhs )                    \
 | 
			
		||||
    { return T( lhs ) OP##= rhs; }                                      \
 | 
			
		||||
};                                                                      \
 | 
			
		||||
                                                                        \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >           \
 | 
			
		||||
struct NAME##1 : B                                                      \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
 | 
			
		||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
 | 
			
		||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
 | 
			
		||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
 | 
			
		||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
 | 
			
		||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
 | 
			
		||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
 | 
			
		||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
 | 
			
		||||
 | 
			
		||||
#undef BOOST_BINARY_OPERATOR_COMMUTATIVE
 | 
			
		||||
#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
 | 
			
		||||
#undef BOOST_OPERATOR2_LEFT
 | 
			
		||||
 | 
			
		||||
//  incrementable and decrementable contributed by Jeremy Siek
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct incrementable : B
 | 
			
		||||
{
 | 
			
		||||
  friend T operator++(T& x, int)
 | 
			
		||||
  {
 | 
			
		||||
    incrementable_type nrv(x);
 | 
			
		||||
    ++x;
 | 
			
		||||
    return nrv;
 | 
			
		||||
  }
 | 
			
		||||
private: // The use of this typedef works around a Borland bug
 | 
			
		||||
  typedef T incrementable_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct decrementable : B
 | 
			
		||||
{
 | 
			
		||||
  friend T operator--(T& x, int)
 | 
			
		||||
  {
 | 
			
		||||
    decrementable_type nrv(x);
 | 
			
		||||
    --x;
 | 
			
		||||
    return nrv;
 | 
			
		||||
  }
 | 
			
		||||
private: // The use of this typedef works around a Borland bug
 | 
			
		||||
  typedef T decrementable_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//  Iterator operator classes (contributed by Jeremy Siek) ------------------//
 | 
			
		||||
 | 
			
		||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct dereferenceable : B
 | 
			
		||||
{
 | 
			
		||||
  P operator->() const
 | 
			
		||||
  { 
 | 
			
		||||
    return &*static_cast<const T&>(*this); 
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct indexable : B
 | 
			
		||||
{
 | 
			
		||||
  R operator[](I n) const
 | 
			
		||||
  {
 | 
			
		||||
    return *(static_cast<const T&>(*this) + n);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//  More operator classes (contributed by Daryle Walker) --------------------//
 | 
			
		||||
//  (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
#define BOOST_BINARY_OPERATOR( NAME, OP )                                     \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >        \
 | 
			
		||||
struct NAME##2 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( const T& lhs, const U& rhs )                          \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 | 
			
		||||
};                                                                            \
 | 
			
		||||
                                                                              \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >                 \
 | 
			
		||||
struct NAME##1 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( const T& lhs, const T& rhs )                          \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
#define BOOST_BINARY_OPERATOR( NAME, OP )                                     \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >        \
 | 
			
		||||
struct NAME##2 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; }       \
 | 
			
		||||
};                                                                            \
 | 
			
		||||
                                                                              \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >                 \
 | 
			
		||||
struct NAME##1 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; }       \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
BOOST_BINARY_OPERATOR( left_shiftable, << )
 | 
			
		||||
BOOST_BINARY_OPERATOR( right_shiftable, >> )
 | 
			
		||||
 | 
			
		||||
#undef BOOST_BINARY_OPERATOR
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct equivalent2 : B
 | 
			
		||||
{
 | 
			
		||||
  friend bool operator==(const T& x, const U& y)
 | 
			
		||||
  {
 | 
			
		||||
    return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct equivalent1 : B
 | 
			
		||||
{
 | 
			
		||||
  friend bool operator==(const T&x, const T&y)
 | 
			
		||||
  {
 | 
			
		||||
    return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct partially_ordered2 : B
 | 
			
		||||
{
 | 
			
		||||
  friend bool operator<=(const T& x, const U& y)
 | 
			
		||||
    { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
 | 
			
		||||
  friend bool operator>=(const T& x, const U& y)
 | 
			
		||||
    { return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
 | 
			
		||||
  friend bool operator>(const U& x, const T& y)
 | 
			
		||||
    { return y < x; }
 | 
			
		||||
  friend bool operator<(const U& x, const T& y)
 | 
			
		||||
    { return y > x; }
 | 
			
		||||
  friend bool operator<=(const U& x, const T& y)
 | 
			
		||||
    { return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
 | 
			
		||||
  friend bool operator>=(const U& x, const T& y)
 | 
			
		||||
    { return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct partially_ordered1 : B
 | 
			
		||||
{
 | 
			
		||||
  friend bool operator>(const T& x, const T& y)
 | 
			
		||||
    { return y < x; }
 | 
			
		||||
  friend bool operator<=(const T& x, const T& y)
 | 
			
		||||
    { return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
 | 
			
		||||
  friend bool operator>=(const T& x, const T& y)
 | 
			
		||||
    { return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//  Combined operator classes (contributed by Daryle Walker) ----------------//
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct totally_ordered2
 | 
			
		||||
    : less_than_comparable2<T, U
 | 
			
		||||
    , equality_comparable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct totally_ordered1
 | 
			
		||||
    : less_than_comparable1<T
 | 
			
		||||
    , equality_comparable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct additive2
 | 
			
		||||
    : addable2<T, U
 | 
			
		||||
    , subtractable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct additive1
 | 
			
		||||
    : addable1<T
 | 
			
		||||
    , subtractable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct multiplicative2
 | 
			
		||||
    : multipliable2<T, U
 | 
			
		||||
    , dividable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct multiplicative1
 | 
			
		||||
    : multipliable1<T
 | 
			
		||||
    , dividable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct integer_multiplicative2
 | 
			
		||||
    : multiplicative2<T, U
 | 
			
		||||
    , modable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct integer_multiplicative1
 | 
			
		||||
    : multiplicative1<T
 | 
			
		||||
    , modable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct arithmetic2
 | 
			
		||||
    : additive2<T, U
 | 
			
		||||
    , multiplicative2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct arithmetic1
 | 
			
		||||
    : additive1<T
 | 
			
		||||
    , multiplicative1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct integer_arithmetic2
 | 
			
		||||
    : additive2<T, U
 | 
			
		||||
    , integer_multiplicative2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct integer_arithmetic1
 | 
			
		||||
    : additive1<T
 | 
			
		||||
    , integer_multiplicative1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct bitwise2
 | 
			
		||||
    : xorable2<T, U
 | 
			
		||||
    , andable2<T, U
 | 
			
		||||
    , orable2<T, U, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct bitwise1
 | 
			
		||||
    : xorable1<T
 | 
			
		||||
    , andable1<T
 | 
			
		||||
    , orable1<T, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct unit_steppable
 | 
			
		||||
    : incrementable<T
 | 
			
		||||
    , decrementable<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct shiftable2
 | 
			
		||||
    : left_shiftable2<T, U
 | 
			
		||||
    , right_shiftable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct shiftable1
 | 
			
		||||
    : left_shiftable1<T
 | 
			
		||||
    , right_shiftable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct ring_operators2
 | 
			
		||||
    : additive2<T, U
 | 
			
		||||
    , subtractable2_left<T, U
 | 
			
		||||
    , multipliable2<T, U, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct ring_operators1
 | 
			
		||||
    : additive1<T
 | 
			
		||||
    , multipliable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct ordered_ring_operators2
 | 
			
		||||
    : ring_operators2<T, U
 | 
			
		||||
    , totally_ordered2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct ordered_ring_operators1
 | 
			
		||||
    : ring_operators1<T
 | 
			
		||||
    , totally_ordered1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct field_operators2
 | 
			
		||||
    : ring_operators2<T, U
 | 
			
		||||
    , dividable2<T, U
 | 
			
		||||
    , dividable2_left<T, U, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct field_operators1
 | 
			
		||||
    : ring_operators1<T
 | 
			
		||||
    , dividable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct ordered_field_operators2
 | 
			
		||||
    : field_operators2<T, U
 | 
			
		||||
    , totally_ordered2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct ordered_field_operators1
 | 
			
		||||
    : field_operators1<T
 | 
			
		||||
    , totally_ordered1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct euclidian_ring_operators2
 | 
			
		||||
    : ring_operators2<T, U
 | 
			
		||||
    , dividable2<T, U
 | 
			
		||||
    , dividable2_left<T, U
 | 
			
		||||
    , modable2<T, U
 | 
			
		||||
    , modable2_left<T, U, B
 | 
			
		||||
      > > > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct euclidian_ring_operators1
 | 
			
		||||
    : ring_operators1<T
 | 
			
		||||
    , dividable1<T
 | 
			
		||||
    , modable1<T, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct ordered_euclidian_ring_operators2
 | 
			
		||||
    : totally_ordered2<T, U
 | 
			
		||||
    , euclidian_ring_operators2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct ordered_euclidian_ring_operators1
 | 
			
		||||
    : totally_ordered1<T
 | 
			
		||||
    , euclidian_ring_operators1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
      
 | 
			
		||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct input_iteratable
 | 
			
		||||
    : equality_comparable1<T
 | 
			
		||||
    , incrementable<T
 | 
			
		||||
    , dereferenceable<T, P, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct output_iteratable
 | 
			
		||||
    : incrementable<T, B
 | 
			
		||||
      > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct forward_iteratable
 | 
			
		||||
    : input_iteratable<T, P, B
 | 
			
		||||
      > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct bidirectional_iteratable
 | 
			
		||||
    : forward_iteratable<T, P
 | 
			
		||||
    , decrementable<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
//  To avoid repeated derivation from equality_comparable,
 | 
			
		||||
//  which is an indirect base class of bidirectional_iterable,
 | 
			
		||||
//  random_access_iteratable must not be derived from totally_ordered1
 | 
			
		||||
//  but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
 | 
			
		||||
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
 | 
			
		||||
struct random_access_iteratable
 | 
			
		||||
    : bidirectional_iteratable<T, P
 | 
			
		||||
    , less_than_comparable1<T
 | 
			
		||||
    , additive2<T, D
 | 
			
		||||
    , indexable<T, D, R, B
 | 
			
		||||
      > > > > {};
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
} // namespace boost
 | 
			
		||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
 | 
			
		||||
//
 | 
			
		||||
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
 | 
			
		||||
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
 | 
			
		||||
// for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
 | 
			
		||||
// two-argument forms. Note that these macros expect to be invoked from within
 | 
			
		||||
// boost.
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
  // The template is already in boost so we have nothing to do.
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE4(template_name)
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE3(template_name)
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE2(template_name)
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE1(template_name)
 | 
			
		||||
 | 
			
		||||
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#  ifndef BOOST_NO_USING_TEMPLATE
 | 
			
		||||
 | 
			
		||||
     // Bring the names in with a using-declaration
 | 
			
		||||
     // to avoid stressing the compiler.
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
 | 
			
		||||
 | 
			
		||||
#  else
 | 
			
		||||
 | 
			
		||||
     // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
 | 
			
		||||
     // from working, we are forced to use inheritance for that compiler.
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE4(template_name)                                             \
 | 
			
		||||
     template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
 | 
			
		||||
     struct template_name : ::template_name<T, U, V, W, B> {};
 | 
			
		||||
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE3(template_name)                                    \
 | 
			
		||||
     template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
 | 
			
		||||
     struct template_name : ::template_name<T, U, V, B> {};
 | 
			
		||||
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE2(template_name)                           \
 | 
			
		||||
     template <class T, class U, class B = ::boost::detail::empty_base<T> > \
 | 
			
		||||
     struct template_name : ::template_name<T, U, B> {};
 | 
			
		||||
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE1(template_name)                  \
 | 
			
		||||
     template <class T, class B = ::boost::detail::empty_base<T> > \
 | 
			
		||||
     struct template_name : ::template_name<T, B> {};
 | 
			
		||||
 | 
			
		||||
#  endif // BOOST_NO_USING_TEMPLATE
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Here's where we put it all together, defining the xxxx forms of the templates
 | 
			
		||||
// in namespace boost. We also define specializations of is_chained_base<> for
 | 
			
		||||
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
 | 
			
		||||
// necessary.
 | 
			
		||||
//
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
// is_chained_base<> - a traits class used to distinguish whether an operator
 | 
			
		||||
// template argument is being used for base class chaining, or is specifying a
 | 
			
		||||
// 2nd argument type.
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
// A type parameter is used instead of a plain bool because Borland's compiler
 | 
			
		||||
// didn't cope well with the more obvious non-type template parameter.
 | 
			
		||||
namespace detail {
 | 
			
		||||
  struct true_t {};
 | 
			
		||||
  struct false_t {};
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
// Unspecialized version assumes that most types are not being used for base
 | 
			
		||||
// class chaining. We specialize for the operator templates defined in this
 | 
			
		||||
// library.
 | 
			
		||||
template<class T> struct is_chained_base {
 | 
			
		||||
  typedef ::boost::detail::false_t value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
// Import a 4-type-argument operator template into boost (if necessary) and
 | 
			
		||||
// provide a specialization of 'is_chained_base<>' for it.
 | 
			
		||||
# define BOOST_OPERATOR_TEMPLATE4(template_name4)                     \
 | 
			
		||||
  BOOST_IMPORT_TEMPLATE4(template_name4)                              \
 | 
			
		||||
  template<class T, class U, class V, class W, class B>               \
 | 
			
		||||
  struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > {  \
 | 
			
		||||
    typedef ::boost::detail::true_t value;                            \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// Import a 3-type-argument operator template into boost (if necessary) and
 | 
			
		||||
// provide a specialization of 'is_chained_base<>' for it.
 | 
			
		||||
# define BOOST_OPERATOR_TEMPLATE3(template_name3)                     \
 | 
			
		||||
  BOOST_IMPORT_TEMPLATE3(template_name3)                              \
 | 
			
		||||
  template<class T, class U, class V, class B>                        \
 | 
			
		||||
  struct is_chained_base< ::boost::template_name3<T, U, V, B> > {     \
 | 
			
		||||
    typedef ::boost::detail::true_t value;                            \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// Import a 2-type-argument operator template into boost (if necessary) and
 | 
			
		||||
// provide a specialization of 'is_chained_base<>' for it.
 | 
			
		||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2)                  \
 | 
			
		||||
  BOOST_IMPORT_TEMPLATE2(template_name2)                           \
 | 
			
		||||
  template<class T, class U, class B>                              \
 | 
			
		||||
  struct is_chained_base< ::boost::template_name2<T, U, B> > {     \
 | 
			
		||||
    typedef ::boost::detail::true_t value;                         \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// Import a 1-type-argument operator template into boost (if necessary) and
 | 
			
		||||
// provide a specialization of 'is_chained_base<>' for it.
 | 
			
		||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1)                  \
 | 
			
		||||
  BOOST_IMPORT_TEMPLATE1(template_name1)                           \
 | 
			
		||||
  template<class T, class B>                                       \
 | 
			
		||||
  struct is_chained_base< ::boost::template_name1<T, B> > {        \
 | 
			
		||||
    typedef ::boost::detail::true_t value;                         \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
 | 
			
		||||
// can be used for specifying both 1-argument and 2-argument forms. Requires the
 | 
			
		||||
// existence of two previously defined class templates named '<template_name>1'
 | 
			
		||||
// and '<template_name>2' which must implement the corresponding 1- and 2-
 | 
			
		||||
// argument forms.
 | 
			
		||||
//
 | 
			
		||||
// The template type parameter O == is_chained_base<U>::value is used to
 | 
			
		||||
// distinguish whether the 2nd argument to <template_name> is being used for
 | 
			
		||||
// base class chaining from another boost operator template or is describing a
 | 
			
		||||
// 2nd operand type. O == true_t only when U is actually an another operator
 | 
			
		||||
// template from the library. Partial specialization is used to select an
 | 
			
		||||
// implementation in terms of either '<template_name>1' or '<template_name>2'.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
# define BOOST_OPERATOR_TEMPLATE(template_name)                    \
 | 
			
		||||
template <class T                                                  \
 | 
			
		||||
         ,class U = T                                              \
 | 
			
		||||
         ,class B = ::boost::detail::empty_base<T>                 \
 | 
			
		||||
         ,class O = typename is_chained_base<U>::value             \
 | 
			
		||||
         >                                                         \
 | 
			
		||||
struct template_name : template_name##2<T, U, B> {};               \
 | 
			
		||||
                                                                   \
 | 
			
		||||
template<class T, class U, class B>                                \
 | 
			
		||||
struct template_name<T, U, B, ::boost::detail::true_t>             \
 | 
			
		||||
  : template_name##1<T, U> {};                                     \
 | 
			
		||||
                                                                   \
 | 
			
		||||
template <class T, class B>                                        \
 | 
			
		||||
struct template_name<T, T, B, ::boost::detail::false_t>            \
 | 
			
		||||
  : template_name##1<T, B> {};                                     \
 | 
			
		||||
                                                                   \
 | 
			
		||||
template<class T, class U, class B, class O>                       \
 | 
			
		||||
struct is_chained_base< ::boost::template_name<T, U, B, O> > {     \
 | 
			
		||||
  typedef ::boost::detail::true_t value;                           \
 | 
			
		||||
};                                                                 \
 | 
			
		||||
                                                                   \
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(template_name##2)                         \
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE1(template_name##1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
#  define BOOST_OPERATOR_TEMPLATE4(template_name4) \
 | 
			
		||||
        BOOST_IMPORT_TEMPLATE4(template_name4)
 | 
			
		||||
#  define BOOST_OPERATOR_TEMPLATE3(template_name3) \
 | 
			
		||||
        BOOST_IMPORT_TEMPLATE3(template_name3)
 | 
			
		||||
#  define BOOST_OPERATOR_TEMPLATE2(template_name2) \
 | 
			
		||||
        BOOST_IMPORT_TEMPLATE2(template_name2)
 | 
			
		||||
#  define BOOST_OPERATOR_TEMPLATE1(template_name1) \
 | 
			
		||||
        BOOST_IMPORT_TEMPLATE1(template_name1)
 | 
			
		||||
 | 
			
		||||
   // In this case we can only assume that template_name<> is equivalent to the
 | 
			
		||||
   // more commonly needed template_name1<> form.
 | 
			
		||||
#  define BOOST_OPERATOR_TEMPLATE(template_name)                   \
 | 
			
		||||
   template <class T, class B = ::boost::detail::empty_base<T> >   \
 | 
			
		||||
   struct template_name : template_name##1<T, B> {};
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
    
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(equality_comparable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(multipliable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(addable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(subtractable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(dividable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(dividable2_left)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(modable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(modable2_left)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(xorable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(andable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(orable)
 | 
			
		||||
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE1(incrementable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE1(decrementable)
 | 
			
		||||
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE3(indexable)
 | 
			
		||||
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(left_shiftable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(right_shiftable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(equivalent)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(partially_ordered)
 | 
			
		||||
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(totally_ordered)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(additive)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(multiplicative)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(arithmetic)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(bitwise)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(shiftable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(ring_operators)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(field_operators)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(input_iteratable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE1(output_iteratable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
 | 
			
		||||
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE4
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE3
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE2
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE1
 | 
			
		||||
#undef BOOST_IMPORT_TEMPLATE1
 | 
			
		||||
#undef BOOST_IMPORT_TEMPLATE2
 | 
			
		||||
#undef BOOST_IMPORT_TEMPLATE3
 | 
			
		||||
#undef BOOST_IMPORT_TEMPLATE4
 | 
			
		||||
 | 
			
		||||
// The following 'operators' classes can only be used portably if the derived class
 | 
			
		||||
// declares ALL of the required member operators.
 | 
			
		||||
template <class T, class U>
 | 
			
		||||
struct operators2
 | 
			
		||||
    : totally_ordered2<T,U
 | 
			
		||||
    , integer_arithmetic2<T,U
 | 
			
		||||
    , bitwise2<T,U
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
template <class T, class U = T>
 | 
			
		||||
struct operators : operators2<T, U> {};
 | 
			
		||||
 | 
			
		||||
template <class T> struct operators<T, T>
 | 
			
		||||
#else
 | 
			
		||||
template <class T> struct operators
 | 
			
		||||
#endif
 | 
			
		||||
    : totally_ordered<T
 | 
			
		||||
    , integer_arithmetic<T
 | 
			
		||||
    , bitwise<T
 | 
			
		||||
    , unit_steppable<T
 | 
			
		||||
      > > > > {};
 | 
			
		||||
 | 
			
		||||
//  Iterator helper classes (contributed by Jeremy Siek) -------------------//
 | 
			
		||||
//  (Input and output iterator helpers contributed by Daryle Walker) -------//
 | 
			
		||||
//  (Changed to use combined operator classes by Daryle Walker) ------------//
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V,
 | 
			
		||||
          class D = std::ptrdiff_t,
 | 
			
		||||
          class P = V const *,
 | 
			
		||||
          class R = V const &>
 | 
			
		||||
struct input_iterator_helper
 | 
			
		||||
  : input_iteratable<T, P
 | 
			
		||||
  , boost::iterator<std::input_iterator_tag, V, D, P, R
 | 
			
		||||
    > > {};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct output_iterator_helper
 | 
			
		||||
  : output_iteratable<T
 | 
			
		||||
  , boost::iterator<std::output_iterator_tag, void, void, void, void
 | 
			
		||||
  > >
 | 
			
		||||
{
 | 
			
		||||
  T& operator*()  { return static_cast<T&>(*this); }
 | 
			
		||||
  T& operator++() { return static_cast<T&>(*this); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V,
 | 
			
		||||
          class D = std::ptrdiff_t,
 | 
			
		||||
          class P = V*,
 | 
			
		||||
          class R = V&>
 | 
			
		||||
struct forward_iterator_helper
 | 
			
		||||
  : forward_iteratable<T, P
 | 
			
		||||
  , boost::iterator<std::forward_iterator_tag, V, D, P, R
 | 
			
		||||
    > > {};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V,
 | 
			
		||||
          class D = std::ptrdiff_t,
 | 
			
		||||
          class P = V*,
 | 
			
		||||
          class R = V&>
 | 
			
		||||
struct bidirectional_iterator_helper
 | 
			
		||||
  : bidirectional_iteratable<T, P
 | 
			
		||||
  , boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
 | 
			
		||||
    > > {};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V, 
 | 
			
		||||
          class D = std::ptrdiff_t,
 | 
			
		||||
          class P = V*,
 | 
			
		||||
          class R = V&>
 | 
			
		||||
struct random_access_iterator_helper
 | 
			
		||||
  : random_access_iteratable<T, P, D, R
 | 
			
		||||
  , boost::iterator<std::random_access_iterator_tag, V, D, P, R
 | 
			
		||||
    > >
 | 
			
		||||
{
 | 
			
		||||
  friend D requires_difference_operator(const T& x, const T& y) {
 | 
			
		||||
    return x - y;
 | 
			
		||||
  }
 | 
			
		||||
}; // random_access_iterator_helper
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#if defined(__sgi) && !defined(__GNUC__)
 | 
			
		||||
#pragma reset woff 1234
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_OPERATORS_HPP
 | 
			
		||||
							
								
								
									
										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 J<>rvi (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
 | 
			
		||||
							
								
								
									
										19
									
								
								include/boost/utility.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								include/boost/utility.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
//  Boost utility.hpp header file  -------------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  Copyright 1999-2003 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/libs/utility/> for the library's home page.
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_UTILITY_HPP
 | 
			
		||||
#define BOOST_UTILITY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/utility/addressof.hpp>
 | 
			
		||||
#include <boost/utility/base_from_member.hpp>  
 | 
			
		||||
#include <boost/utility/enable_if.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/next_prior.hpp>
 | 
			
		||||
#include <boost/noncopyable.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // BOOST_UTILITY_HPP
 | 
			
		||||
							
								
								
									
										58
									
								
								include/boost/utility/addressof.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								include/boost/utility/addressof.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
// Copyright (C) 2002 Brad King (brad.king@kitware.com) 
 | 
			
		||||
//                    Douglas Gregor (gregod@cs.rpi.edu)
 | 
			
		||||
//                    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 {
 | 
			
		||||
 | 
			
		||||
// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov)
 | 
			
		||||
 | 
			
		||||
// VC7 strips const from nested classes unless we add indirection here
 | 
			
		||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
 | 
			
		||||
 | 
			
		||||
template<class T> struct _addp
 | 
			
		||||
{
 | 
			
		||||
    typedef T * type;
 | 
			
		||||
};
 | 
			
		||||
    
 | 
			
		||||
template <typename T> typename _addp<T>::type
 | 
			
		||||
 | 
			
		||||
# else
 | 
			
		||||
template <typename T> T*
 | 
			
		||||
# endif
 | 
			
		||||
addressof(T& v)
 | 
			
		||||
{
 | 
			
		||||
  return reinterpret_cast<T*>(
 | 
			
		||||
       &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										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 J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_UTILITY_ENABLE_IF_HPP
 | 
			
		||||
#define BOOST_UTILITY_ENABLE_IF_HPP
 | 
			
		||||
 | 
			
		||||
#include "boost/config.hpp"
 | 
			
		||||
 | 
			
		||||
// Even the definition of enable_if causes problems on some compilers,
 | 
			
		||||
// so it's macroed out for all compilers that do not support SFINAE
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_SFINAE
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
  template <bool B, class T = void>
 | 
			
		||||
  struct enable_if_c {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct enable_if_c<false, T> {};
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = void> 
 | 
			
		||||
  struct enable_if : public enable_if_c<Cond::value, T> {};
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T>
 | 
			
		||||
  struct lazy_enable_if_c {
 | 
			
		||||
    typedef typename T::type type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct lazy_enable_if_c<false, T> {};
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T> 
 | 
			
		||||
  struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = void>
 | 
			
		||||
  struct disable_if_c {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct disable_if_c<true, T> {};
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = void> 
 | 
			
		||||
  struct disable_if : public disable_if_c<Cond::value, T> {};
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T>
 | 
			
		||||
  struct lazy_disable_if_c {
 | 
			
		||||
    typedef typename T::type type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct lazy_disable_if_c<true, T> {};
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T> 
 | 
			
		||||
  struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  namespace detail { typedef void enable_if_default_T; }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct enable_if_does_not_work_on_this_compiler;
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = detail::enable_if_default_T>
 | 
			
		||||
  struct enable_if_c : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct disable_if_c : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct enable_if : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct disable_if : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct lazy_enable_if : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct lazy_disable_if : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_SFINAE
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										89
									
								
								include/boost/utility/result_of.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								include/boost/utility/result_of.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
 | 
			
		||||
#ifndef BOOST_RESULT_OF_HPP
 | 
			
		||||
#define BOOST_RESULT_OF_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/preprocessor/iteration/iterate.hpp> 
 | 
			
		||||
#include <boost/preprocessor/punctuation/comma_if.hpp> 
 | 
			
		||||
#include <boost/preprocessor/repetition/enum_params.hpp> 
 | 
			
		||||
#include <boost/preprocessor/repetition/enum_shifted_params.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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										127
									
								
								include/boost/utility/value_init.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								include/boost/utility/value_init.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
			
		||||
// (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
 | 
			
		||||
// 18 Feb 2008 (Worked around compiler bugs, added initialized_value) Fernando Cacciola, Niels Dekker
 | 
			
		||||
//
 | 
			
		||||
#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
 | 
			
		||||
{
 | 
			
		||||
  public :
 | 
			
		||||
    
 | 
			
		||||
    template <class T> operator T() const
 | 
			
		||||
    {
 | 
			
		||||
      return get( value_initialized<T>() );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // 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>
 | 
			
		||||
							
								
								
									
										11
									
								
								iterator_adaptors.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								iterator_adaptors.htm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
<!-- 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 http-equiv="refresh" content="0; URL=../iterator/doc/index.html">
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
This documentation moved to <a href="../iterator/doc/index.html">../iterator/doc/index.html</a>.
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										324
									
								
								iterators_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								iterators_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,324 @@
 | 
			
		||||
//  Demonstrate and test boost/operators.hpp on std::iterators  --------------//
 | 
			
		||||
 | 
			
		||||
//  (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)
 | 
			
		||||
 | 
			
		||||
#define  BOOST_INCLUDE_MAIN
 | 
			
		||||
#include <boost/test/test_tools.hpp>  // for main
 | 
			
		||||
 | 
			
		||||
#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<
 | 
			
		||||
     test_iter<T,R,P>, T, std::ptrdiff_t, P, R>
 | 
			
		||||
{
 | 
			
		||||
  typedef test_iter self;
 | 
			
		||||
  typedef R Reference;
 | 
			
		||||
  typedef std::ptrdiff_t Distance;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  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; }
 | 
			
		||||
  self& operator++() { ++_i; return *this; }
 | 
			
		||||
  self& operator--() { --_i; return *this; }
 | 
			
		||||
  self& operator+=(Distance n) { _i += n; return *this; }
 | 
			
		||||
  self& operator-=(Distance n) { _i -= n; return *this; }
 | 
			
		||||
  bool operator==(const self& x) const { return _i == x._i; }
 | 
			
		||||
  bool operator<(const self& x) const { return _i < x._i; }
 | 
			
		||||
  friend Distance operator-(const self& x, const self& y) {
 | 
			
		||||
    return x._i - y._i; 
 | 
			
		||||
  }
 | 
			
		||||
protected:
 | 
			
		||||
  P _i;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Iterator operator testing classes
 | 
			
		||||
class test_opr_base
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
    // Test data and types
 | 
			
		||||
    BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u );
 | 
			
		||||
 | 
			
		||||
    typedef std::string  fruit_array_type[ fruit_length ];
 | 
			
		||||
 | 
			
		||||
    static  fruit_array_type    fruit;
 | 
			
		||||
 | 
			
		||||
};  // test_opr_base
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
template <typename T, typename R = T&, typename P = T*>
 | 
			
		||||
class test_opr
 | 
			
		||||
    : public test_opr_base
 | 
			
		||||
{
 | 
			
		||||
    typedef test_opr<T, R, P>  self_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    // Types
 | 
			
		||||
    typedef T  value_type;
 | 
			
		||||
    typedef R  reference;
 | 
			
		||||
    typedef P  pointer;
 | 
			
		||||
 | 
			
		||||
    typedef test_iter<T, R, P>  iter_type;
 | 
			
		||||
 | 
			
		||||
    // Test controller
 | 
			
		||||
    static  void  master_test( char const name[] );
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    // Test data
 | 
			
		||||
    static iter_type const  fruit_begin;
 | 
			
		||||
    static iter_type const  fruit_end;
 | 
			
		||||
 | 
			
		||||
    // 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_opr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Class-static data definitions
 | 
			
		||||
test_opr_base::fruit_array_type
 | 
			
		||||
 test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" };
 | 
			
		||||
 | 
			
		||||
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 );
 | 
			
		||||
 | 
			
		||||
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 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 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 ");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								noncopyable_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								noncopyable_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
//  boost class noncopyable test program  ------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (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.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//   9 Jun 99  Add unnamed namespace
 | 
			
		||||
//   2 Jun 99  Initial Version
 | 
			
		||||
 | 
			
		||||
#include <boost/noncopyable.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
//  This program demonstrates compiler errors resulting from trying to copy
 | 
			
		||||
//  construct or copy assign a class object derived from class noncopyable.
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
    class DontTreadOnMe : private boost::noncopyable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
         DontTreadOnMe() { std::cout << "defanged!" << std::endl; }
 | 
			
		||||
    };   // DontTreadOnMe
 | 
			
		||||
 | 
			
		||||
}   // unnamed namespace
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    DontTreadOnMe object1;
 | 
			
		||||
    DontTreadOnMe object2(object1);
 | 
			
		||||
    object1 = object2;
 | 
			
		||||
    return 0;
 | 
			
		||||
}   // main
 | 
			
		||||
  
 | 
			
		||||
							
								
								
									
										405
									
								
								numeric_traits_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								numeric_traits_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,405 @@
 | 
			
		||||
//  (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
 | 
			
		||||
//              warnings with fancy compilers. Added commentary and
 | 
			
		||||
//              additional dumping of traits data for tested types (David
 | 
			
		||||
//              Abrahams).
 | 
			
		||||
//  21 Jan 2001 Initial version (David Abrahams)
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/numeric_traits.hpp>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <boost/type_traits.hpp>
 | 
			
		||||
#include <boost/static_assert.hpp>
 | 
			
		||||
#include <boost/cstdint.hpp>
 | 
			
		||||
#include <boost/utility.hpp>
 | 
			
		||||
#include <boost/lexical_cast.hpp>
 | 
			
		||||
#include <climits>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#ifndef BOOST_NO_LIMITS
 | 
			
		||||
# include <limits>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// =================================================================================
 | 
			
		||||
// template class complement_traits<Number> --
 | 
			
		||||
//
 | 
			
		||||
//    statically computes the max and min for 1s and 2s-complement binary
 | 
			
		||||
//    numbers. This helps on platforms without <limits> support. It also shows
 | 
			
		||||
//    an example of a recursive template that works with MSVC!
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template <unsigned size> struct complement; // forward
 | 
			
		||||
 | 
			
		||||
// The template complement, below, does all the real work, using "poor man's
 | 
			
		||||
// partial specialization". We need complement_traits_aux<> so that MSVC doesn't
 | 
			
		||||
// complain about undefined min/max as we're trying to recursively define them. 
 | 
			
		||||
template <class Number, unsigned size>
 | 
			
		||||
struct complement_traits_aux
 | 
			
		||||
{
 | 
			
		||||
    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>
 | 
			
		||||
struct complement
 | 
			
		||||
{
 | 
			
		||||
    template <class Number>
 | 
			
		||||
    struct traits
 | 
			
		||||
    {
 | 
			
		||||
     private:
 | 
			
		||||
        // indirection through complement_traits_aux necessary to keep MSVC happy
 | 
			
		||||
        typedef complement_traits_aux<Number, size - 1> prev;
 | 
			
		||||
     public:
 | 
			
		||||
#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));
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) << CHAR_BIT));
 | 
			
		||||
#endif
 | 
			
		||||
   
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Template class complement_base<> -- defines values for min and max for
 | 
			
		||||
// complement<1>, at the deepest level of recursion. Uses "poor man's partial
 | 
			
		||||
// specialization" again.
 | 
			
		||||
template <bool is_signed> struct complement_base;
 | 
			
		||||
 | 
			
		||||
template <> struct complement_base<false>
 | 
			
		||||
{
 | 
			
		||||
    template <class Number>
 | 
			
		||||
    struct values
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, min = 0);
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, max = UCHAR_MAX);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <> struct complement_base<true>
 | 
			
		||||
{
 | 
			
		||||
    template <class Number>
 | 
			
		||||
    struct values
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, min = SCHAR_MIN);
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, max = SCHAR_MAX);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Base specialization of complement, puts an end to the recursion.
 | 
			
		||||
template <>
 | 
			
		||||
struct complement<1>
 | 
			
		||||
{
 | 
			
		||||
    template <class Number>
 | 
			
		||||
    struct traits
 | 
			
		||||
    {
 | 
			
		||||
        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);
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, max =
 | 
			
		||||
                            complement_base<is_signed>::template values<Number>::max);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Now here's the "pretty" template you're intended to actually use.
 | 
			
		||||
//   complement_traits<Number>::min, complement_traits<Number>::max are the
 | 
			
		||||
//   minimum and maximum values of Number if Number is a built-in integer type.
 | 
			
		||||
template <class Number>
 | 
			
		||||
struct complement_traits
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_CONSTANT(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
 | 
			
		||||
    BOOST_STATIC_CONSTANT(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// =================================================================================
 | 
			
		||||
 | 
			
		||||
// Support for streaming various numeric types in exactly the format I want. I
 | 
			
		||||
// needed this in addition to all the assertions so that I could see exactly
 | 
			
		||||
// what was going on.
 | 
			
		||||
//
 | 
			
		||||
// Numbers go through a 2-stage conversion process (by default, though, no real
 | 
			
		||||
// conversion).
 | 
			
		||||
//
 | 
			
		||||
template <class T> struct stream_as {
 | 
			
		||||
    typedef T t1;
 | 
			
		||||
    typedef T t2;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// char types first get converted to unsigned char, then to unsigned.
 | 
			
		||||
template <> struct stream_as<char> {
 | 
			
		||||
    typedef unsigned char t1;
 | 
			
		||||
    typedef unsigned t2;
 | 
			
		||||
};
 | 
			
		||||
template <> struct stream_as<unsigned char> {
 | 
			
		||||
    typedef unsigned char t1; typedef unsigned t2;
 | 
			
		||||
};
 | 
			
		||||
template <> struct stream_as<signed char>  {
 | 
			
		||||
    typedef unsigned char t1; typedef unsigned t2;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
 | 
			
		||||
 | 
			
		||||
// 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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <> struct stream_as<boost::intmax_t>  {
 | 
			
		||||
    typedef std::string t1;
 | 
			
		||||
    typedef std::string t2;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Standard promotion process for streaming
 | 
			
		||||
template <class T> struct promote
 | 
			
		||||
{
 | 
			
		||||
    static typename stream_as<T>::t1 from(T x) {
 | 
			
		||||
        typedef typename stream_as<T>::t1 t1;
 | 
			
		||||
        return t1(x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#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.
 | 
			
		||||
template <> struct promote<boost::uintmax_t> {
 | 
			
		||||
    std::string static from(const boost::uintmax_t x) {
 | 
			
		||||
        if (x > ULONG_MAX)
 | 
			
		||||
            return std::string("large unsigned value");
 | 
			
		||||
        else
 | 
			
		||||
            return boost::lexical_cast<std::string>((unsigned long)x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
template <> struct promote<boost::intmax_t> {
 | 
			
		||||
    std::string static from(const boost::intmax_t x) {
 | 
			
		||||
        if (x > boost::intmax_t(ULONG_MAX))
 | 
			
		||||
            return std::string("large positive signed value");
 | 
			
		||||
        else if (x >= 0)
 | 
			
		||||
            return boost::lexical_cast<std::string>((unsigned long)x);
 | 
			
		||||
        
 | 
			
		||||
        if (x < boost::intmax_t(LONG_MIN))
 | 
			
		||||
            return std::string("large negative signed value");
 | 
			
		||||
        else
 | 
			
		||||
            return boost::lexical_cast<std::string>((long)x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// This is the function which converts types to the form I want to stream them in.
 | 
			
		||||
template <class T>
 | 
			
		||||
typename stream_as<T>::t2 stream_number(T x)
 | 
			
		||||
{
 | 
			
		||||
    return promote<T>::from(x);
 | 
			
		||||
}
 | 
			
		||||
// =================================================================================
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Tests for built-in signed and unsigned types
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Tag types for selecting tests
 | 
			
		||||
struct unsigned_tag {};
 | 
			
		||||
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*)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
 | 
			
		||||
    BOOST_STATIC_ASSERT(!boost::detail::is_signed<Number>::value);
 | 
			
		||||
    BOOST_STATIC_ASSERT(
 | 
			
		||||
        (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;
 | 
			
		||||
    
 | 
			
		||||
    const Number test_max = (sizeof(Number) < sizeof(boost::intmax_t))
 | 
			
		||||
        ? max
 | 
			
		||||
        : max / 2 - 1;
 | 
			
		||||
 | 
			
		||||
    std::cout << std::hex << "(unsigned) min = " << stream_number(min) << ", max = "
 | 
			
		||||
              << stream_number(max) << "..." << std::flush;
 | 
			
		||||
    std::cout << "difference_type = " << typeid(difference_type).name() << "..."
 | 
			
		||||
              << std::flush;
 | 
			
		||||
    
 | 
			
		||||
    difference_type d1 = boost::detail::numeric_distance(Number(0), test_max);
 | 
			
		||||
    difference_type d2 = boost::detail::numeric_distance(test_max, Number(0));
 | 
			
		||||
    
 | 
			
		||||
    std::cout << "0->" << stream_number(test_max) << "==" << std::dec << stream_number(d1) << "; "
 | 
			
		||||
              << std::hex << stream_number(test_max) << "->0==" << std::dec << stream_number(d2) << "..." << std::flush;
 | 
			
		||||
 | 
			
		||||
    assert(d1 == difference_type(test_max));
 | 
			
		||||
    assert(d2 == -difference_type(test_max));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests for signed numbers. The extra default Number parameter works around an
 | 
			
		||||
// MSVC bug.
 | 
			
		||||
struct out_of_range_tag {};
 | 
			
		||||
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*)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
 | 
			
		||||
    typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
 | 
			
		||||
    const Number max = complement_traits<Number>::max;
 | 
			
		||||
    const Number min = complement_traits<Number>::min;
 | 
			
		||||
    
 | 
			
		||||
    difference_type d1 = boost::detail::numeric_distance(min, max);
 | 
			
		||||
    difference_type d2 = boost::detail::numeric_distance(max, min);
 | 
			
		||||
 | 
			
		||||
    std::cout << stream_number(min) << "->" << stream_number(max) << "==";
 | 
			
		||||
    std::cout << std::dec << stream_number(d1) << "; ";
 | 
			
		||||
    std::cout << std::hex << stream_number(max) << "->" << stream_number(min)
 | 
			
		||||
              << "==" << std::dec << stream_number(d2) << "..." << std::flush;
 | 
			
		||||
    assert(d1 == difference_type(max) - difference_type(min));
 | 
			
		||||
    assert(d2 == difference_type(min) - difference_type(max));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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*)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
 | 
			
		||||
    typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
 | 
			
		||||
    const Number max = complement_traits<Number>::max;
 | 
			
		||||
    const Number min = complement_traits<Number>::min;
 | 
			
		||||
 | 
			
		||||
    difference_type min_distance = complement_traits<difference_type>::min;
 | 
			
		||||
    difference_type max_distance = complement_traits<difference_type>::max;
 | 
			
		||||
 | 
			
		||||
    const Number n1 = Number(min + max_distance);
 | 
			
		||||
    const Number n2 = Number(max + min_distance);
 | 
			
		||||
    difference_type d1 = boost::detail::numeric_distance(min, n1);
 | 
			
		||||
    difference_type d2 = boost::detail::numeric_distance(max, n2);
 | 
			
		||||
 | 
			
		||||
    std::cout << stream_number(min) << "->" << stream_number(n1) << "==";
 | 
			
		||||
    std::cout << std::dec << stream_number(d1) << "; ";
 | 
			
		||||
    std::cout << std::hex << stream_number(max) << "->" << stream_number(n2)
 | 
			
		||||
              << "==" << std::dec << stream_number(d2) << "..." << std::flush;
 | 
			
		||||
    assert(d1 == max_distance);
 | 
			
		||||
    assert(d2 == min_distance);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Number>
 | 
			
		||||
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);
 | 
			
		||||
    BOOST_STATIC_ASSERT(
 | 
			
		||||
        (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;
 | 
			
		||||
    
 | 
			
		||||
    std::cout << std::hex << "min = " << stream_number(min) << ", max = "
 | 
			
		||||
              << stream_number(max) << "..." << std::flush;
 | 
			
		||||
    std::cout << "difference_type = " << typeid(difference_type).name() << "..."
 | 
			
		||||
              << std::flush;
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::detail::if_true<
 | 
			
		||||
                          (sizeof(Number) < sizeof(boost::intmax_t))>
 | 
			
		||||
                        ::template then<
 | 
			
		||||
                          in_range_tag,
 | 
			
		||||
                          out_of_range_tag
 | 
			
		||||
                        >::type
 | 
			
		||||
        range_tag;
 | 
			
		||||
    signed_test<Number>(range_tag(), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Test for all numbers. The extra default Number parameter works around an MSVC
 | 
			
		||||
// bug.
 | 
			
		||||
template <class Number>
 | 
			
		||||
void test(Number* = 0)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "testing " << typeid(Number).name() << ":\n"
 | 
			
		||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
 | 
			
		||||
              << "is_signed: " << (std::numeric_limits<Number>::is_signed ? "true\n" : "false\n")
 | 
			
		||||
              << "is_bounded: " << (std::numeric_limits<Number>::is_bounded ? "true\n" : "false\n")
 | 
			
		||||
              << "digits: " << std::numeric_limits<Number>::digits << "\n"
 | 
			
		||||
#endif
 | 
			
		||||
              << "..." << std::flush;
 | 
			
		||||
 | 
			
		||||
    // factoring out difference_type for the assert below confused Borland :(
 | 
			
		||||
    typedef boost::detail::is_signed<
 | 
			
		||||
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
 | 
			
		||||
        typename
 | 
			
		||||
#endif
 | 
			
		||||
        boost::detail::numeric_traits<Number>::difference_type
 | 
			
		||||
        > is_signed;
 | 
			
		||||
    BOOST_STATIC_ASSERT(is_signed::value);
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::detail::if_true<
 | 
			
		||||
        boost::detail::is_signed<Number>::value
 | 
			
		||||
        >::template then<signed_tag, unsigned_tag>::type signedness;
 | 
			
		||||
    
 | 
			
		||||
    test_aux<Number>(signedness(), 0);
 | 
			
		||||
    std::cout << "passed" << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    test<char>();
 | 
			
		||||
    test<unsigned char>();
 | 
			
		||||
    test<signed char>();
 | 
			
		||||
    test<wchar_t>();
 | 
			
		||||
    test<short>();
 | 
			
		||||
    test<unsigned short>();
 | 
			
		||||
    test<int>();
 | 
			
		||||
    test<unsigned int>();
 | 
			
		||||
    test<long>();
 | 
			
		||||
    test<unsigned 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.
 | 
			
		||||
    // test<boost::uintmax_t>();
 | 
			
		||||
    // test<boost::intmax_t>();
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2133
									
								
								operators.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2133
									
								
								operators.htm
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										941
									
								
								operators_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										941
									
								
								operators_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,941 @@
 | 
			
		||||
//  Demonstrate and test boost/operators.hpp  -------------------------------//
 | 
			
		||||
 | 
			
		||||
//  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/libs/utility for documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  03 Apr 08 Added convertible_to_bool (Daniel Frey)
 | 
			
		||||
//  01 Oct 01 Added tests for "left" operators
 | 
			
		||||
//            and new grouped operators. (Helmut Zeisel)
 | 
			
		||||
//  20 May 01 Output progress messages.  Added tests for new operator
 | 
			
		||||
//            templates.  Updated random number generator.  Changed tests to
 | 
			
		||||
//            use Boost Test Tools library.  (Daryle Walker)
 | 
			
		||||
//  04 Jun 00 Added regression test for a bug I found (David Abrahams)
 | 
			
		||||
//  17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy)
 | 
			
		||||
//  ?? ??? 00 Major update to randomly test all one- and two- argument forms by
 | 
			
		||||
//            wrapping integral types and comparing the results of operations
 | 
			
		||||
//            to the results for the raw types (David Abrahams)
 | 
			
		||||
//  12 Dec 99 Minor update, output confirmation message.
 | 
			
		||||
//  15 Nov 99 Initial version
 | 
			
		||||
 | 
			
		||||
#define BOOST_INCLUDE_MAIN
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>                      // for BOOST_MSVC
 | 
			
		||||
#include <boost/cstdlib.hpp>                     // for boost::exit_success
 | 
			
		||||
#include <boost/operators.hpp>                   // for the tested items
 | 
			
		||||
#include <boost/random/linear_congruential.hpp>  // for boost::minstd_rand
 | 
			
		||||
#include <boost/test/test_tools.hpp>             // for main
 | 
			
		||||
 | 
			
		||||
#include <iostream>  // for std::cout (std::endl indirectly)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
    // avoiding a template version of true_value so as to not confuse VC++
 | 
			
		||||
    int true_value(int x) { return x; }
 | 
			
		||||
    long true_value(long x) { return x; }
 | 
			
		||||
    signed char true_value(signed char x) { return x; }
 | 
			
		||||
    short true_value(short x) { return x; }
 | 
			
		||||
    unsigned int true_value(unsigned int x) { return x; }
 | 
			
		||||
    unsigned long true_value(unsigned long x) { return x; }
 | 
			
		||||
    unsigned char true_value(unsigned char x) { return x; }
 | 
			
		||||
    unsigned short true_value(unsigned short x) { return x; }
 | 
			
		||||
 | 
			
		||||
    // verify the minimum requirements for some operators
 | 
			
		||||
    class convertible_to_bool
 | 
			
		||||
    {
 | 
			
		||||
    private:
 | 
			
		||||
        bool _value;
 | 
			
		||||
 | 
			
		||||
        typedef bool convertible_to_bool::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
        void operator!() const;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        convertible_to_bool( const bool value ) : _value( value ) {}
 | 
			
		||||
 | 
			
		||||
        operator unspecified_bool_type() const
 | 
			
		||||
          { return _value ? &convertible_to_bool::_value : 0; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // The use of operators<> here tended to obscure
 | 
			
		||||
    // interactions with certain compiler bugs
 | 
			
		||||
    template <class T>
 | 
			
		||||
    class Wrapped1
 | 
			
		||||
        : boost::operators<Wrapped1<T> >
 | 
			
		||||
        , boost::shiftable<Wrapped1<T> >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped1( T v = T() ) : _value(v) {}
 | 
			
		||||
        T value() const { return _value; }
 | 
			
		||||
 | 
			
		||||
        convertible_to_bool operator<(const Wrapped1& x) const
 | 
			
		||||
          { return _value < x._value; }
 | 
			
		||||
        convertible_to_bool operator==(const Wrapped1& x) const
 | 
			
		||||
          { return _value == x._value; }
 | 
			
		||||
        
 | 
			
		||||
        Wrapped1& operator+=(const Wrapped1& x)
 | 
			
		||||
          { _value += x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator-=(const Wrapped1& x)
 | 
			
		||||
          { _value -= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator*=(const Wrapped1& x)
 | 
			
		||||
          { _value *= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator/=(const Wrapped1& x)
 | 
			
		||||
          { _value /= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator%=(const Wrapped1& x)
 | 
			
		||||
          { _value %= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator|=(const Wrapped1& x)
 | 
			
		||||
          { _value |= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator&=(const Wrapped1& x)
 | 
			
		||||
          { _value &= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator^=(const Wrapped1& x)
 | 
			
		||||
          { _value ^= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator<<=(const Wrapped1& x)
 | 
			
		||||
          { _value <<= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator>>=(const Wrapped1& x)
 | 
			
		||||
          { _value >>= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator++()               { ++_value; return *this; }
 | 
			
		||||
        Wrapped1& operator--()               { --_value; return *this; }
 | 
			
		||||
        
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T>
 | 
			
		||||
    T true_value(Wrapped1<T> x) { return x.value(); }    
 | 
			
		||||
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    class Wrapped2
 | 
			
		||||
        : boost::operators<Wrapped2<T, U> >
 | 
			
		||||
        , boost::operators2<Wrapped2<T, U>, U>
 | 
			
		||||
        , boost::shiftable1<Wrapped2<T, U>
 | 
			
		||||
        , boost::shiftable2<Wrapped2<T, U>, U > >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped2( T v = T() ) : _value(v) {}
 | 
			
		||||
        T value() const { return _value; }
 | 
			
		||||
 | 
			
		||||
        convertible_to_bool operator<(const Wrapped2& x) const
 | 
			
		||||
          { return _value < x._value; }
 | 
			
		||||
        convertible_to_bool operator==(const Wrapped2& x) const
 | 
			
		||||
          { return _value == x._value; }
 | 
			
		||||
        
 | 
			
		||||
        Wrapped2& operator+=(const Wrapped2& x)
 | 
			
		||||
          { _value += x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator-=(const Wrapped2& x)
 | 
			
		||||
          { _value -= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator*=(const Wrapped2& x)
 | 
			
		||||
          { _value *= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator/=(const Wrapped2& x)
 | 
			
		||||
          { _value /= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator%=(const Wrapped2& x)
 | 
			
		||||
          { _value %= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator|=(const Wrapped2& x)
 | 
			
		||||
          { _value |= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator&=(const Wrapped2& x)
 | 
			
		||||
          { _value &= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator^=(const Wrapped2& x)
 | 
			
		||||
          { _value ^= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator<<=(const Wrapped2& x)
 | 
			
		||||
          { _value <<= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator>>=(const Wrapped2& x)
 | 
			
		||||
          { _value >>= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator++()                { ++_value; return *this; }
 | 
			
		||||
        Wrapped2& operator--()                { --_value; return *this; }
 | 
			
		||||
         
 | 
			
		||||
        convertible_to_bool operator<(U u) const
 | 
			
		||||
          { return _value < u; }
 | 
			
		||||
        convertible_to_bool operator>(U u) const
 | 
			
		||||
          { return _value > u; }
 | 
			
		||||
        convertible_to_bool operator==(U u) const
 | 
			
		||||
          { return _value == u; }
 | 
			
		||||
 | 
			
		||||
        Wrapped2& operator+=(U u) { _value += u; return *this; }
 | 
			
		||||
        Wrapped2& operator-=(U u) { _value -= u; return *this; }
 | 
			
		||||
        Wrapped2& operator*=(U u) { _value *= u; return *this; }
 | 
			
		||||
        Wrapped2& operator/=(U u) { _value /= u; return *this; }
 | 
			
		||||
        Wrapped2& operator%=(U u) { _value %= u; return *this; }
 | 
			
		||||
        Wrapped2& operator|=(U u) { _value |= u; return *this; }
 | 
			
		||||
        Wrapped2& operator&=(U u) { _value &= u; return *this; }
 | 
			
		||||
        Wrapped2& operator^=(U u) { _value ^= u; return *this; }
 | 
			
		||||
        Wrapped2& operator<<=(U u) { _value <<= u; return *this; }
 | 
			
		||||
        Wrapped2& operator>>=(U u) { _value >>= u; return *this; }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    T true_value(Wrapped2<T,U> x) { return x.value(); }
 | 
			
		||||
    
 | 
			
		||||
    template <class T>
 | 
			
		||||
    class Wrapped3
 | 
			
		||||
        : boost::equivalent<Wrapped3<T> >
 | 
			
		||||
        , boost::partially_ordered<Wrapped3<T> >
 | 
			
		||||
        , boost::equality_comparable<Wrapped3<T> >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped3( T v = T() ) : _value(v) {}
 | 
			
		||||
        T value() const { return _value; }
 | 
			
		||||
 | 
			
		||||
        convertible_to_bool operator<(const Wrapped3& x) const
 | 
			
		||||
          { return _value < x._value; }
 | 
			
		||||
        
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T>
 | 
			
		||||
    T true_value(Wrapped3<T> x) { return x.value(); }    
 | 
			
		||||
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    class Wrapped4
 | 
			
		||||
        : boost::equality_comparable1<Wrapped4<T, U>
 | 
			
		||||
        , boost::equivalent1<Wrapped4<T, U>
 | 
			
		||||
        , boost::partially_ordered1<Wrapped4<T, U> > > >
 | 
			
		||||
        , boost::partially_ordered2<Wrapped4<T, U>, U
 | 
			
		||||
        , boost::equivalent2<Wrapped4<T, U>, U
 | 
			
		||||
        , boost::equality_comparable2<Wrapped4<T, U>, U> > >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped4( T v = T() ) : _value(v) {}
 | 
			
		||||
        T value() const { return _value; }
 | 
			
		||||
 | 
			
		||||
        convertible_to_bool operator<(const Wrapped4& x) const
 | 
			
		||||
          { return _value < x._value; }
 | 
			
		||||
         
 | 
			
		||||
        convertible_to_bool operator<(U u) const
 | 
			
		||||
          { return _value < u; }
 | 
			
		||||
        convertible_to_bool operator>(U u) const
 | 
			
		||||
          { return _value > u; }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    T true_value(Wrapped4<T,U> x) { return x.value(); }
 | 
			
		||||
    
 | 
			
		||||
    // U must be convertible to T
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    class Wrapped5
 | 
			
		||||
        : boost::ordered_field_operators2<Wrapped5<T, U>, U>
 | 
			
		||||
        , boost::ordered_field_operators1<Wrapped5<T, U> >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped5( T v = T() ) : _value(v) {}
 | 
			
		||||
 | 
			
		||||
        // Conversion from U to Wrapped5<T,U>
 | 
			
		||||
        Wrapped5(U u) : _value(u) {}
 | 
			
		||||
 | 
			
		||||
        T value() const { return _value; }
 | 
			
		||||
 | 
			
		||||
        convertible_to_bool operator<(const Wrapped5& x) const
 | 
			
		||||
          { return _value < x._value; }
 | 
			
		||||
        convertible_to_bool operator<(U u) const
 | 
			
		||||
          { return _value < u; }
 | 
			
		||||
        convertible_to_bool operator>(U u) const
 | 
			
		||||
          { return _value > u; }
 | 
			
		||||
        convertible_to_bool operator==(const Wrapped5& u) const
 | 
			
		||||
          { return _value == u._value; }
 | 
			
		||||
        convertible_to_bool operator==(U u) const
 | 
			
		||||
          { return _value == u; }
 | 
			
		||||
 | 
			
		||||
        Wrapped5& operator/=(const Wrapped5& u) { _value /= u._value; return *this;}
 | 
			
		||||
        Wrapped5& operator/=(U u) { _value /= u; return *this;}
 | 
			
		||||
        Wrapped5& operator*=(const Wrapped5& u) { _value *= u._value; return *this;}
 | 
			
		||||
        Wrapped5& operator*=(U u) { _value *= u; return *this;}
 | 
			
		||||
        Wrapped5& operator-=(const Wrapped5& u) { _value -= u._value; return *this;}
 | 
			
		||||
        Wrapped5& operator-=(U u) { _value -= u; return *this;}
 | 
			
		||||
        Wrapped5& operator+=(const Wrapped5& u) { _value += u._value; return *this;}
 | 
			
		||||
        Wrapped5& operator+=(U u) { _value += u; return *this;}
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    T true_value(Wrapped5<T,U> x) { return x.value(); }
 | 
			
		||||
    
 | 
			
		||||
    // U must be convertible to T
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    class Wrapped6
 | 
			
		||||
        : boost::ordered_euclidian_ring_operators2<Wrapped6<T, U>, U>
 | 
			
		||||
        , boost::ordered_euclidian_ring_operators1<Wrapped6<T, U> >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped6( T v = T() ) : _value(v) {}
 | 
			
		||||
 | 
			
		||||
        // Conversion from U to Wrapped6<T,U>
 | 
			
		||||
        Wrapped6(U u) : _value(u) {}
 | 
			
		||||
 | 
			
		||||
        T value() const { return _value; }
 | 
			
		||||
 | 
			
		||||
        convertible_to_bool operator<(const Wrapped6& x) const
 | 
			
		||||
          { return _value < x._value; }
 | 
			
		||||
        convertible_to_bool operator<(U u) const
 | 
			
		||||
          { return _value < u; }
 | 
			
		||||
        convertible_to_bool operator>(U u) const
 | 
			
		||||
          { return _value > u; }
 | 
			
		||||
        convertible_to_bool operator==(const Wrapped6& u) const
 | 
			
		||||
          { return _value == u._value; }
 | 
			
		||||
        convertible_to_bool operator==(U u) const
 | 
			
		||||
          { return _value == u; }
 | 
			
		||||
 | 
			
		||||
        Wrapped6& operator%=(const Wrapped6& u) { _value %= u._value; return *this;}
 | 
			
		||||
        Wrapped6& operator%=(U u) { _value %= u; return *this;}
 | 
			
		||||
        Wrapped6& operator/=(const Wrapped6& u) { _value /= u._value; return *this;}
 | 
			
		||||
        Wrapped6& operator/=(U u) { _value /= u; return *this;}
 | 
			
		||||
        Wrapped6& operator*=(const Wrapped6& u) { _value *= u._value; return *this;}
 | 
			
		||||
        Wrapped6& operator*=(U u) { _value *= u; return *this;}
 | 
			
		||||
        Wrapped6& operator-=(const Wrapped6& u) { _value -= u._value; return *this;}
 | 
			
		||||
        Wrapped6& operator-=(U u) { _value -= u; return *this;}
 | 
			
		||||
        Wrapped6& operator+=(const Wrapped6& u) { _value += u._value; return *this;}
 | 
			
		||||
        Wrapped6& operator+=(U u) { _value += u; return *this;}
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    T true_value(Wrapped6<T,U> x) { return x.value(); }
 | 
			
		||||
    
 | 
			
		||||
    //  MyInt uses only the single template-argument form of all_operators<>
 | 
			
		||||
    typedef Wrapped1<int> MyInt;
 | 
			
		||||
 | 
			
		||||
    typedef Wrapped2<long, long> MyLong;
 | 
			
		||||
 | 
			
		||||
    typedef Wrapped3<signed char> MyChar;
 | 
			
		||||
 | 
			
		||||
    typedef Wrapped4<short, short> MyShort;
 | 
			
		||||
 | 
			
		||||
    typedef Wrapped5<double, int> MyDoubleInt;
 | 
			
		||||
 | 
			
		||||
    typedef Wrapped6<long, int> MyLongInt;
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_CHECK( true_value(y1) == true_value(y2) );
 | 
			
		||||
        BOOST_CHECK( true_value(x1) == true_value(x2) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_CHECK( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
 | 
			
		||||
        BOOST_CHECK( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
 | 
			
		||||
        BOOST_CHECK( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
 | 
			
		||||
        BOOST_CHECK( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_less_than_comparable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_less_than_comparable_aux( y1, x1, y2, x2 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_CHECK( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
 | 
			
		||||
        BOOST_CHECK( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_equality_comparable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_equality_comparable_aux( y1, x1, y2, x2 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_CHECK( (x1 * y1).value() == (x2 * y2) );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_multipliable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_multipliable_aux( y1, x1, y2, x2 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  template <class A, class B>
 | 
			
		||||
  void test_value_equality(A a, B b)
 | 
			
		||||
  {
 | 
			
		||||
      BOOST_CHECK(a.value() == b);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
#define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2)
 | 
			
		||||
#define TEST_OP_L(op) test_value_equality(y1 op x1, y2 op x2)
 | 
			
		||||
  
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        TEST_OP_R(+);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_addable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_addable_aux( y1, x1, y2, x2 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        TEST_OP_R(-);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_subtractable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        TEST_OP_L(-);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        if ( y2 != 0 )
 | 
			
		||||
            TEST_OP_R(/);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_dividable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        if ( x2 != 0 )
 | 
			
		||||
            TEST_OP_L(/);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        if ( y2 != 0 )
 | 
			
		||||
            TEST_OP_R(%);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_modable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        if ( x2 != 0 )
 | 
			
		||||
            TEST_OP_L(%);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        TEST_OP_R(^);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_xorable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_xorable_aux( y1, x1, y2, x2 );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        TEST_OP_R(&);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_andable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_andable_aux( y1, x1, y2, x2 );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        TEST_OP_R(|);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_orable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_orable_aux( y1, x1, y2, x2 );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_left_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        TEST_OP_R(<<);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_right_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        TEST_OP_R(>>);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class X2>
 | 
			
		||||
    void test_incrementable(X1 x1, X2 x2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, x1, x2, x2 );
 | 
			
		||||
        BOOST_CHECK( (x1++).value() == x2++ );
 | 
			
		||||
        BOOST_CHECK( x1.value() == x2 );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class X2>
 | 
			
		||||
    void test_decrementable(X1 x1, X2 x2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, x1, x2, x2 );
 | 
			
		||||
        BOOST_CHECK( (x1--).value() == x2-- );
 | 
			
		||||
        BOOST_CHECK( x1.value() == x2 );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        test_less_than_comparable( x1, y1, x2, y2 );
 | 
			
		||||
        test_equality_comparable( x1, y1, x2, y2 );
 | 
			
		||||
        test_multipliable( x1, y1, x2, y2 );
 | 
			
		||||
        test_addable( x1, y1, x2, y2 );
 | 
			
		||||
        test_subtractable( x1, y1, x2, y2 );
 | 
			
		||||
        test_dividable( x1, y1, x2, y2 );
 | 
			
		||||
        test_modable( x1, y1, x2, y2 );
 | 
			
		||||
        test_xorable( x1, y1, x2, y2 );
 | 
			
		||||
        test_andable( x1, y1, x2, y2 );
 | 
			
		||||
        test_orable( x1, y1, x2, y2 );
 | 
			
		||||
        test_left_shiftable( x1, y1, x2, y2 );
 | 
			
		||||
        test_right_shiftable( x1, y1, x2, y2 );
 | 
			
		||||
        test_incrementable( x1, x2 );
 | 
			
		||||
        test_decrementable( x1, x2 );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        test_subtractable_left( x1, y1, x2, y2 );
 | 
			
		||||
        test_dividable_left( x1, y1, x2, y2 );
 | 
			
		||||
        test_modable_left( x1, y1, x2, y2 );
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
    template <class Big, class Small>
 | 
			
		||||
    struct tester
 | 
			
		||||
    {
 | 
			
		||||
        void operator()(boost::minstd_rand& randomizer) const
 | 
			
		||||
        {
 | 
			
		||||
            Big    b1 = Big( randomizer() );
 | 
			
		||||
            Big    b2 = Big( randomizer() );
 | 
			
		||||
            Small  s = Small( randomizer() );
 | 
			
		||||
            
 | 
			
		||||
            test_all( Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2 );
 | 
			
		||||
            test_all( Wrapped2<Big, Small>(b1), s, b1, s );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template <class Big, class Small>
 | 
			
		||||
    struct tester_left
 | 
			
		||||
    {
 | 
			
		||||
        void operator()(boost::minstd_rand& randomizer) const
 | 
			
		||||
        {
 | 
			
		||||
            Big    b1 = Big( randomizer() );
 | 
			
		||||
            Small  s = Small( randomizer() );
 | 
			
		||||
            
 | 
			
		||||
            test_left( Wrapped6<Big, Small>(b1), s, b1, s );
 | 
			
		||||
         }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // added as a regression test. We had a bug which this uncovered.
 | 
			
		||||
    struct Point
 | 
			
		||||
        : boost::addable<Point
 | 
			
		||||
        , boost::subtractable<Point> >
 | 
			
		||||
    {
 | 
			
		||||
        Point( int h, int v ) : h(h), v(v) {}
 | 
			
		||||
        Point() :h(0), v(0) {}
 | 
			
		||||
        const Point& operator+=( const Point& rhs )
 | 
			
		||||
            { h += rhs.h; v += rhs.v; return *this; }
 | 
			
		||||
        const Point& operator-=( const Point& rhs )
 | 
			
		||||
            { h -= rhs.h; v -= rhs.v; return *this; }
 | 
			
		||||
 | 
			
		||||
        int h;
 | 
			
		||||
        int v;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
} // unnamed namespace
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// workaround for MSVC bug; for some reasons the compiler doesn't instantiate
 | 
			
		||||
// inherited operator templates at the moment it must, so the following
 | 
			
		||||
// explicit instantiations force it to do that.
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC) && (_MSC_VER < 1300)
 | 
			
		||||
template Wrapped1<int>;
 | 
			
		||||
template Wrapped1<long>;
 | 
			
		||||
template Wrapped1<unsigned int>;
 | 
			
		||||
template Wrapped1<unsigned long>;
 | 
			
		||||
 | 
			
		||||
template Wrapped2<int, int>;
 | 
			
		||||
template Wrapped2<int, signed char>;
 | 
			
		||||
template Wrapped2<long, signed char>;
 | 
			
		||||
template Wrapped2<long, int>;
 | 
			
		||||
template Wrapped2<long, long>;
 | 
			
		||||
template Wrapped2<unsigned int, unsigned int>;
 | 
			
		||||
template Wrapped2<unsigned int, unsigned char>;
 | 
			
		||||
template Wrapped2<unsigned long, unsigned int>;
 | 
			
		||||
template Wrapped2<unsigned long, unsigned char>;
 | 
			
		||||
template Wrapped2<unsigned long, unsigned long>;
 | 
			
		||||
 | 
			
		||||
template Wrapped6<long, int>;
 | 
			
		||||
template Wrapped6<long, signed char>;
 | 
			
		||||
template Wrapped6<int, signed char>;
 | 
			
		||||
template Wrapped6<unsigned long, unsigned int>;
 | 
			
		||||
template Wrapped6<unsigned long, unsigned char>;
 | 
			
		||||
template Wrapped6<unsigned int, unsigned char>;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PRIVATE_EXPR_TEST(e, t)  BOOST_CHECK( ((e), (t)) )
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
test_main( int , char * [] )
 | 
			
		||||
{
 | 
			
		||||
    using std::cout;
 | 
			
		||||
    using std::endl;
 | 
			
		||||
 | 
			
		||||
    // Regression test.
 | 
			
		||||
    Point x;
 | 
			
		||||
    x = x + Point(3, 4);
 | 
			
		||||
    x = x - Point(3, 4);
 | 
			
		||||
    
 | 
			
		||||
    cout << "Created point, and operated on it." << endl;
 | 
			
		||||
    
 | 
			
		||||
    for (int n = 0; n < 1000; ++n)  // was 10,000 but took too long (Beman)
 | 
			
		||||
    {
 | 
			
		||||
        boost::minstd_rand r;
 | 
			
		||||
        tester<long, int>()(r);
 | 
			
		||||
        tester<long, signed char>()(r);
 | 
			
		||||
        tester<long, long>()(r);
 | 
			
		||||
        tester<int, int>()(r);
 | 
			
		||||
        tester<int, signed char>()(r);
 | 
			
		||||
        
 | 
			
		||||
        tester<unsigned long, unsigned int>()(r);
 | 
			
		||||
        tester<unsigned long, unsigned char>()(r);
 | 
			
		||||
        tester<unsigned long, unsigned long>()(r);
 | 
			
		||||
        tester<unsigned int, unsigned int>()(r);
 | 
			
		||||
        tester<unsigned int, unsigned char>()(r);
 | 
			
		||||
 | 
			
		||||
        tester_left<long, int>()(r);
 | 
			
		||||
        tester_left<long, signed char>()(r);
 | 
			
		||||
        tester_left<int, signed char>()(r);
 | 
			
		||||
 | 
			
		||||
        tester_left<unsigned long, unsigned int>()(r);
 | 
			
		||||
        tester_left<unsigned long, unsigned char>()(r);
 | 
			
		||||
        tester_left<unsigned int, unsigned char>()(r);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    cout << "Did random tester loop." << endl;
 | 
			
		||||
 | 
			
		||||
    MyInt i1(1);
 | 
			
		||||
    MyInt i2(2);
 | 
			
		||||
    MyInt i;
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( i1.value() == 1 );
 | 
			
		||||
    BOOST_CHECK( i2.value() == 2 );
 | 
			
		||||
    BOOST_CHECK( i.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyInt objects.\n";
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(i2 == i) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(i1 != i2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(i1 <  i2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(i1 <= i2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(i <= i2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(i2 >  i1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(i2 >= i1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(i2 >= i) );
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i - i1), (i.value() == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i * i2), (i.value() == 8) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i / i2), (i.value() == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i % ( i - i1 )), (i.value() == 1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i2 + i2), (i.value() == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i1 | i2 | i), (i.value() == 7) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i & i2), (i.value() == 2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i + i1), (i.value() == 3) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i ^ i1), (i.value() == 2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = ( i + i1 ) * ( i2 | i1 )), (i.value() == 9) );
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i1 << i2), (i.value() == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i2 >> i1), (i.value() == 1) );
 | 
			
		||||
 | 
			
		||||
    cout << "Performed tests on MyInt objects.\n";
 | 
			
		||||
 | 
			
		||||
    MyLong j1(1);
 | 
			
		||||
    MyLong j2(2);
 | 
			
		||||
    MyLong j;
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( j1.value() == 1 );
 | 
			
		||||
    BOOST_CHECK( j2.value() == 2 );
 | 
			
		||||
    BOOST_CHECK( j.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyLong objects.\n";
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j2 == j) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 == j) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j2 == 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j == j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j1 != j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j1 != 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 != j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j1 <  j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 <  j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j1 <  2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j1 <= j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 <= j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j1 <= j) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j <= j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 <= j2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j <= 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j2 >  j1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 >  j1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j2 >  1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j2 >= j1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 >= j1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j2 >= 1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j2 >= j) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 >= j) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(j2 >= 2) );
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j1 + 2) == 3) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((1 + j2) == 3) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j + 2) == 5) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((3 + j2) == 5) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j - 1) == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j * 2) == 8) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((4 * j2) == 8) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j / 2) == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j % 3) == 1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((1 | j2 | j) == 7) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j1 | 2 | j) == 7) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j1 | j2 | 4) == 7) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((7 & j2) == 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j & 2) == 2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((3 ^ j1) == 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j ^ 1) == 2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j1 << 2) == 4) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j2 << 1) == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j >> 2) == 1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>((j2 >> 1) == 1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyLong objects.\n";
 | 
			
		||||
 | 
			
		||||
    MyChar k1(1);
 | 
			
		||||
    MyChar k2(2);
 | 
			
		||||
    MyChar k;
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( k1.value() == 1 );
 | 
			
		||||
    BOOST_CHECK( k2.value() == 2 );
 | 
			
		||||
    BOOST_CHECK( k.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyChar objects.\n";
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(k2 == k) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(k1 != k2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(k1 <  k2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(k1 <= k2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(k <= k2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(k2 >  k1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(k2 >= k1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(k2 >= k) );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyChar objects.\n";
 | 
			
		||||
 | 
			
		||||
    MyShort l1(1);
 | 
			
		||||
    MyShort l2(2);
 | 
			
		||||
    MyShort l;
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( l1.value() == 1 );
 | 
			
		||||
    BOOST_CHECK( l2.value() == 2 );
 | 
			
		||||
    BOOST_CHECK( l.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyShort objects.\n";
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l2 == l) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 == l) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l2 == 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l == l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l1 != l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l1 != 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 != l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l1 <  l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 <  l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l1 <  2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l1 <= l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 <= l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l1 <= l) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l <= l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 <= l2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l <= 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l2 >  l1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 >  l1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l2 >  1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l2 >= l1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 >= l1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l2 >= 1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l2 >= l) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 >= l) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(l2 >= 2) );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyShort objects.\n";
 | 
			
		||||
    
 | 
			
		||||
    MyDoubleInt di1(1);
 | 
			
		||||
    MyDoubleInt di2(2.);
 | 
			
		||||
    MyDoubleInt half(0.5);
 | 
			
		||||
    MyDoubleInt di;
 | 
			
		||||
    MyDoubleInt tmp;
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( di1.value() == 1 );
 | 
			
		||||
    BOOST_CHECK( di2.value() == 2 );
 | 
			
		||||
    BOOST_CHECK( di2.value() == 2 );
 | 
			
		||||
    BOOST_CHECK( di.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyDoubleInt objects.\n";
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di2 == di) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 == di) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di == 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di1 < di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 < di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di1 <= di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 <= di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di2 > di1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di2 > 1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di2 >= di1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di2 >= 1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di1 / di2 == half) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di1 / 2 == half) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 / di2 == half) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di1 * di2 == di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di1 * 2 == di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 * di2 == di2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di2 - di1 == di1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di2 - 1 == di1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 - di1 == di1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di1 + di1 == di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(di1 + 1 == di2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 + di1 == di2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) );
 | 
			
		||||
 | 
			
		||||
    cout << "Performed tests on MyDoubleInt objects.\n";
 | 
			
		||||
 | 
			
		||||
    MyLongInt li1(1);
 | 
			
		||||
    MyLongInt li2(2);
 | 
			
		||||
    MyLongInt li;
 | 
			
		||||
    MyLongInt tmp2;
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK( li1.value() == 1 );
 | 
			
		||||
    BOOST_CHECK( li2.value() == 2 );
 | 
			
		||||
    BOOST_CHECK( li.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyLongInt objects.\n";
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li2 == li) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 == li) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li == 2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 < li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 < li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 <= li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 <= li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li2 > li1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li2 > 1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li2 >= li1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li2 >= 1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 % li2 == li1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 % 2 == li1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 % li2 == li1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 / li2 == 0) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 / 2 == 0) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 / li2 == 0) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 * li2 == li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 * 2 == li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 * li2 == li2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li2 - li1 == li1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li2 - 1 == li1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(2 - li1 == li1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 + li1 == li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(li1 + 1 == li2) );
 | 
			
		||||
    BOOST_CHECK( static_cast<bool>(1 + li1 == li2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) );
 | 
			
		||||
 | 
			
		||||
    cout << "Performed tests on MyLongInt objects.\n";
 | 
			
		||||
 | 
			
		||||
    return boost::exit_success;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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.
 | 
			
		||||
							
								
								
									
										37
									
								
								test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
# 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 ../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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								throw_exception.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								throw_exception.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>Boost: throw_exception.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>throw_exception.hpp</h1>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td colspan="2" height="64"> </td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</table>
 | 
			
		||||
		<p>
 | 
			
		||||
			The header <STRONG><boost/throw_exception.hpp></STRONG> defines the 
 | 
			
		||||
			helper function <STRONG>boost::throw_exception</STRONG>. It is intended to be 
 | 
			
		||||
			used in Boost libraries that need to throw exceptions, but support 
 | 
			
		||||
			configurations and platforms where exceptions aren't available, as indicated by 
 | 
			
		||||
			the presence of the <STRONG>BOOST_NO_EXCEPTIONS</STRONG> <A href="../config/config.htm#macro_ref">
 | 
			
		||||
				configuration macro</A>.
 | 
			
		||||
		</p>
 | 
			
		||||
		<P>When <STRONG>BOOST_NO_EXCEPTIONS</STRONG> is not defined, <tt>boost::throw_exception(e)</tt>
 | 
			
		||||
			is equivalent to <tt>throw e</tt>. Otherwise, the function is left undefined, 
 | 
			
		||||
			and the user is expected to supply an appropriate definition. Callers of <tt>throw_exception</tt>
 | 
			
		||||
			are allowed to assume that the function never returns; therefore, if the 
 | 
			
		||||
			user-defined <tt>throw_exception</tt> returns, the behavior is undefined.</P>
 | 
			
		||||
		<h3><a name="Synopsis">Synopsis</a></h3>
 | 
			
		||||
		<pre>
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
void throw_exception(std::exception const & e); // user defined
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
template<class E> void throw_exception(E const & e)
 | 
			
		||||
{
 | 
			
		||||
    throw e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
		<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>
 | 
			
		||||
@@ -1,659 +0,0 @@
 | 
			
		||||
//  (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.
 | 
			
		||||
 | 
			
		||||
// standalone test program for <boost/type_traits.hpp>
 | 
			
		||||
 | 
			
		||||
/* Release notes:
 | 
			
		||||
   20 Jan 2001:
 | 
			
		||||
      Suppress an expected warning for MSVC
 | 
			
		||||
      Added a test to prove that we can use void with is_same<>
 | 
			
		||||
      Removed "press any key to exit" as it interferes with testing in large
 | 
			
		||||
      batches.
 | 
			
		||||
      (David Abahams)
 | 
			
		||||
   31st July 2000:
 | 
			
		||||
      Added extra tests for is_empty, is_convertible, alignment_of.
 | 
			
		||||
   23rd July 2000:
 | 
			
		||||
      Removed all call_traits tests to call_traits_test.cpp
 | 
			
		||||
      Removed all compressed_pair tests to compressed_pair_tests.cpp
 | 
			
		||||
      Improved tests macros
 | 
			
		||||
      Tidied up specialistions of type_types classes for test cases.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
 | 
			
		||||
#include <boost/type_traits.hpp>
 | 
			
		||||
#include <boost/utility.hpp>
 | 
			
		||||
#include "type_traits_test.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace boost;
 | 
			
		||||
 | 
			
		||||
// Since there is no compiler support, we should specialize:
 | 
			
		||||
//  is_enum for all enumerations (is_enum implies is_POD)
 | 
			
		||||
//  is_union for all unions
 | 
			
		||||
//  is_empty for all empty composites
 | 
			
		||||
//  is_POD for all PODs (except enums) (is_POD implies has_*)
 | 
			
		||||
//  has_* for any UDT that has that trait and is not POD
 | 
			
		||||
 | 
			
		||||
enum enum_UDT{ one, two, three };
 | 
			
		||||
struct UDT
 | 
			
		||||
{
 | 
			
		||||
   UDT();
 | 
			
		||||
   ~UDT();
 | 
			
		||||
   UDT(const UDT&);
 | 
			
		||||
   UDT& operator=(const UDT&);
 | 
			
		||||
   int i;
 | 
			
		||||
 | 
			
		||||
   void f1();
 | 
			
		||||
   int f2();
 | 
			
		||||
   int f3(int);
 | 
			
		||||
   int f4(int, float);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct POD_UDT { int x; };
 | 
			
		||||
struct empty_UDT{ ~empty_UDT(){}; };
 | 
			
		||||
struct empty_POD_UDT{};
 | 
			
		||||
union union_UDT
 | 
			
		||||
{
 | 
			
		||||
  int x;
 | 
			
		||||
  double y;
 | 
			
		||||
  ~union_UDT();
 | 
			
		||||
};
 | 
			
		||||
union POD_union_UDT
 | 
			
		||||
{
 | 
			
		||||
  int x;
 | 
			
		||||
  double y;
 | 
			
		||||
};
 | 
			
		||||
union empty_union_UDT
 | 
			
		||||
{
 | 
			
		||||
  ~empty_union_UDT();
 | 
			
		||||
};
 | 
			
		||||
union empty_POD_union_UDT{};
 | 
			
		||||
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 | 
			
		||||
namespace boost {
 | 
			
		||||
template <> struct is_enum<enum_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_POD<POD_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
// this type is not POD, so we have to specialize the has_* individually
 | 
			
		||||
template <> struct has_trivial_constructor<empty_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct has_trivial_copy<empty_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct has_trivial_assign<empty_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_POD<empty_POD_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_union<union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_union<POD_union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_POD<POD_union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_union<empty_union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
// this type is not POD, so we have to specialize the has_* individually
 | 
			
		||||
template <> struct has_trivial_constructor<empty_union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct has_trivial_copy<empty_union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct has_trivial_assign<empty_union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_union<empty_POD_union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_POD<empty_POD_union_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
namespace boost {
 | 
			
		||||
template <> struct is_enum<enum_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_POD<POD_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
// this type is not POD, so we have to specialize the has_* individually
 | 
			
		||||
template <> struct has_trivial_constructor<empty_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct has_trivial_copy<empty_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct has_trivial_assign<empty_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_POD<empty_POD_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_union<union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_union<POD_union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_POD<POD_union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_union<empty_union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
// this type is not POD, so we have to specialize the has_* individually
 | 
			
		||||
template <> struct has_trivial_constructor<empty_union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct has_trivial_copy<empty_union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct has_trivial_assign<empty_union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_union<empty_POD_union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_POD<empty_POD_union_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class Base { };
 | 
			
		||||
 | 
			
		||||
class Deriverd : public Base { };
 | 
			
		||||
 | 
			
		||||
class NonDerived { };
 | 
			
		||||
 | 
			
		||||
enum enum1
 | 
			
		||||
{
 | 
			
		||||
   one_,two_
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum enum2
 | 
			
		||||
{
 | 
			
		||||
   three_,four_
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct VB
 | 
			
		||||
{
 | 
			
		||||
   virtual ~VB(){};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct VD : VB
 | 
			
		||||
{
 | 
			
		||||
   ~VD(){};
 | 
			
		||||
};
 | 
			
		||||
//
 | 
			
		||||
// struct non_pointer:
 | 
			
		||||
// used to verify that is_pointer does not return
 | 
			
		||||
// true for class types that implement operator void*()
 | 
			
		||||
//
 | 
			
		||||
struct non_pointer
 | 
			
		||||
{
 | 
			
		||||
   operator void*(){return this;}
 | 
			
		||||
};
 | 
			
		||||
//
 | 
			
		||||
// struct non_empty:
 | 
			
		||||
// used to verify that is_empty does not emit
 | 
			
		||||
// spurious warnings or errors.
 | 
			
		||||
//
 | 
			
		||||
struct non_empty : boost::noncopyable
 | 
			
		||||
{
 | 
			
		||||
   int i;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Steve: All comments that I (Steve Cleary) have added below are prefixed with
 | 
			
		||||
//  "Steve:"  The failures that BCB4 has on the tests are due to Borland's
 | 
			
		||||
//  not considering cv-qual's as a part of the type -- they are considered
 | 
			
		||||
//  compiler hints only.  These failures should be fixed before long.
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
   std::cout << "Checking type operations..." << std::endl << std::endl;
 | 
			
		||||
 | 
			
		||||
   // cv-qualifiers applied to reference types should have no effect
 | 
			
		||||
   // declare these here for later use with is_reference and remove_reference:
 | 
			
		||||
   typedef int& r_type;
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(push)
 | 
			
		||||
# pragma warning(disable:4181) // qualifier applied to reference type ignored
 | 
			
		||||
#endif
 | 
			
		||||
   typedef const r_type cr_type;
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   type_test(int, remove_reference<int>::type)
 | 
			
		||||
   type_test(const int, remove_reference<const int>::type)
 | 
			
		||||
   type_test(int, remove_reference<int&>::type)
 | 
			
		||||
   type_test(const int, remove_reference<const int&>::type)
 | 
			
		||||
   type_test(volatile int, remove_reference<volatile int&>::type)
 | 
			
		||||
   type_test(int, remove_reference<cr_type>::type)
 | 
			
		||||
 | 
			
		||||
   type_test(int, remove_const<const int>::type)
 | 
			
		||||
   // Steve: fails on BCB4
 | 
			
		||||
   type_test(volatile int, remove_const<volatile int>::type)
 | 
			
		||||
   // Steve: fails on BCB4
 | 
			
		||||
   type_test(volatile int, remove_const<const volatile int>::type)
 | 
			
		||||
   type_test(int, remove_const<int>::type)
 | 
			
		||||
   type_test(int*, remove_const<int* const>::type)
 | 
			
		||||
   type_test(int, remove_volatile<volatile int>::type)
 | 
			
		||||
   // Steve: fails on BCB4
 | 
			
		||||
   type_test(const int, remove_volatile<const int>::type)
 | 
			
		||||
   // Steve: fails on BCB4
 | 
			
		||||
   type_test(const int, remove_volatile<const volatile int>::type)
 | 
			
		||||
   type_test(int, remove_volatile<int>::type)
 | 
			
		||||
   type_test(int*, remove_volatile<int* volatile>::type)
 | 
			
		||||
   type_test(int, remove_cv<volatile int>::type)
 | 
			
		||||
   type_test(int, remove_cv<const int>::type)
 | 
			
		||||
   type_test(int, remove_cv<const volatile int>::type)
 | 
			
		||||
   type_test(int, remove_cv<int>::type)
 | 
			
		||||
   type_test(int*, remove_cv<int* volatile>::type)
 | 
			
		||||
   type_test(int*, remove_cv<int* const>::type)
 | 
			
		||||
   type_test(int*, remove_cv<int* const volatile>::type)
 | 
			
		||||
   type_test(const int *, remove_cv<const int * const>::type)
 | 
			
		||||
   type_test(int, remove_bounds<int>::type)
 | 
			
		||||
   type_test(int*, remove_bounds<int*>::type)
 | 
			
		||||
   type_test(int, remove_bounds<int[3]>::type)
 | 
			
		||||
   type_test(int[3], remove_bounds<int[2][3]>::type)
 | 
			
		||||
 | 
			
		||||
   std::cout << std::endl << "Checking type properties..." << std::endl << std::endl;
 | 
			
		||||
 | 
			
		||||
   value_test(true, (is_same<void, void>::value))
 | 
			
		||||
   value_test(false, (is_same<int, void>::value))
 | 
			
		||||
   value_test(false, (is_same<void, int>::value))
 | 
			
		||||
   value_test(true, (is_same<int, int>::value))
 | 
			
		||||
   value_test(false, (is_same<int, const int>::value))
 | 
			
		||||
   value_test(false, (is_same<int, int&>::value))
 | 
			
		||||
   value_test(false, (is_same<int*, const int*>::value))
 | 
			
		||||
   value_test(false, (is_same<int*, int*const>::value))
 | 
			
		||||
   value_test(false, (is_same<int, int[2]>::value))
 | 
			
		||||
   value_test(false, (is_same<int*, int[2]>::value))
 | 
			
		||||
   value_test(false, (is_same<int[4], int[2]>::value))
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_const<int>::value)
 | 
			
		||||
   value_test(true, is_const<const int>::value)
 | 
			
		||||
   value_test(false, is_const<volatile int>::value)
 | 
			
		||||
   value_test(true, is_const<const volatile int>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_volatile<int>::value)
 | 
			
		||||
   value_test(false, is_volatile<const int>::value)
 | 
			
		||||
   value_test(true, is_volatile<volatile int>::value)
 | 
			
		||||
   value_test(true, is_volatile<const volatile int>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, is_void<void>::value)
 | 
			
		||||
   // Steve: fails on BCB4
 | 
			
		||||
   // JM: but looks as though it should according to [3.9.3p1]?
 | 
			
		||||
   //value_test(false, is_void<const void>::value)
 | 
			
		||||
   value_test(false, is_void<int>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<UDT>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<void>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<bool>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<char>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<signed char>::value)
 | 
			
		||||
   value_test(true, is_standard_unsigned_integral<unsigned char>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<wchar_t>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<short>::value)
 | 
			
		||||
   value_test(true, is_standard_unsigned_integral<unsigned short>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<int>::value)
 | 
			
		||||
   value_test(true, is_standard_unsigned_integral<unsigned int>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<long>::value)
 | 
			
		||||
   value_test(true, is_standard_unsigned_integral<unsigned long>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<float>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<double>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<long double>::value)
 | 
			
		||||
   #ifdef ULLONG_MAX
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<long long>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<unsigned long long>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
   #if defined(__BORLANDC__) || defined(_MSC_VER)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<__int64>::value)
 | 
			
		||||
   value_test(false, is_standard_unsigned_integral<unsigned __int64>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_standard_signed_integral<UDT>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<void>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<bool>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<char>::value)
 | 
			
		||||
   value_test(true, is_standard_signed_integral<signed char>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<unsigned char>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<wchar_t>::value)
 | 
			
		||||
   value_test(true, is_standard_signed_integral<short>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<unsigned short>::value)
 | 
			
		||||
   value_test(true, is_standard_signed_integral<int>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<unsigned int>::value)
 | 
			
		||||
   value_test(true, is_standard_signed_integral<long>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<unsigned long>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<float>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<double>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<long double>::value)
 | 
			
		||||
   #ifdef ULLONG_MAX
 | 
			
		||||
   value_test(false, is_standard_signed_integral<long long>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<unsigned long long>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
   #if defined(__BORLANDC__) || defined(_MSC_VER)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<__int64>::value)
 | 
			
		||||
   value_test(false, is_standard_signed_integral<unsigned __int64>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_standard_arithmetic<UDT>::value)
 | 
			
		||||
   value_test(false, is_standard_arithmetic<void>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<bool>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<char>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<signed char>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<unsigned char>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<wchar_t>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<short>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<unsigned short>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<int>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<unsigned int>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<long>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<unsigned long>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<float>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<double>::value)
 | 
			
		||||
   value_test(true, is_standard_arithmetic<long double>::value)
 | 
			
		||||
   #ifdef ULLONG_MAX
 | 
			
		||||
   value_test(false, is_standard_arithmetic<long long>::value)
 | 
			
		||||
   value_test(false, is_standard_arithmetic<unsigned long long>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
   #if defined(__BORLANDC__) || defined(_MSC_VER)
 | 
			
		||||
   value_test(false, is_standard_arithmetic<__int64>::value)
 | 
			
		||||
   value_test(false, is_standard_arithmetic<unsigned __int64>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_standard_fundamental<UDT>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<void>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<bool>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<char>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<signed char>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<unsigned char>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<wchar_t>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<short>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<unsigned short>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<int>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<unsigned int>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<long>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<unsigned long>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<float>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<double>::value)
 | 
			
		||||
   value_test(true, is_standard_fundamental<long double>::value)
 | 
			
		||||
   #ifdef ULLONG_MAX
 | 
			
		||||
   value_test(false, is_standard_fundamental<long long>::value)
 | 
			
		||||
   value_test(false, is_standard_fundamental<unsigned long long>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
   #if defined(__BORLANDC__) || defined(_MSC_VER)
 | 
			
		||||
   value_test(false, is_standard_fundamental<__int64>::value)
 | 
			
		||||
   value_test(false, is_standard_fundamental<unsigned __int64>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_arithmetic<UDT>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<char>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<signed char>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<unsigned char>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<wchar_t>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<short>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<unsigned short>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<int>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<unsigned int>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<long>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<unsigned long>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<float>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<double>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<long double>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<bool>::value)
 | 
			
		||||
   #ifdef ULLONG_MAX
 | 
			
		||||
   value_test(true, is_arithmetic<long long>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<unsigned long long>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
   #if defined(__BORLANDC__) || defined(_MSC_VER)
 | 
			
		||||
   value_test(true, is_arithmetic<__int64>::value)
 | 
			
		||||
   value_test(true, is_arithmetic<unsigned __int64>::value)
 | 
			
		||||
   #endif
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_array<int>::value)
 | 
			
		||||
   value_test(false, is_array<int*>::value)
 | 
			
		||||
   value_test(false, is_array<const int*>::value)
 | 
			
		||||
   value_test(false, is_array<const volatile int*>::value)
 | 
			
		||||
   value_test(true, is_array<int[2]>::value)
 | 
			
		||||
   value_test(true, is_array<const int[2]>::value)
 | 
			
		||||
   value_test(true, is_array<const volatile int[2]>::value)
 | 
			
		||||
   value_test(true, is_array<int[2][3]>::value)
 | 
			
		||||
   value_test(true, is_array<UDT[2]>::value)
 | 
			
		||||
   value_test(false, is_array<int(&)[2]>::value)
 | 
			
		||||
 | 
			
		||||
   typedef void(*f1)();
 | 
			
		||||
   typedef int(*f2)(int);
 | 
			
		||||
   typedef int(*f3)(int, bool);
 | 
			
		||||
   typedef void (UDT::*mf1)();
 | 
			
		||||
   typedef int (UDT::*mf2)();
 | 
			
		||||
   typedef int (UDT::*mf3)(int);
 | 
			
		||||
   typedef int (UDT::*mf4)(int, float);
 | 
			
		||||
   
 | 
			
		||||
   value_test(false, is_const<f1>::value)
 | 
			
		||||
   value_test(false, is_reference<f1>::value)
 | 
			
		||||
   value_test(false, is_array<f1>::value)
 | 
			
		||||
   value_test(false, is_pointer<int>::value)
 | 
			
		||||
   value_test(false, is_pointer<int&>::value)
 | 
			
		||||
   value_test(true, is_pointer<int*>::value)
 | 
			
		||||
   value_test(true, is_pointer<const int*>::value)
 | 
			
		||||
   value_test(true, is_pointer<volatile int*>::value)
 | 
			
		||||
   value_test(true, is_pointer<non_pointer*>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
 | 
			
		||||
   value_test(false, is_pointer<int*const>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
 | 
			
		||||
   value_test(false, is_pointer<int*volatile>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
 | 
			
		||||
   value_test(false, is_pointer<int*const volatile>::value)
 | 
			
		||||
   // JM 02 Oct 2000:
 | 
			
		||||
   value_test(false, is_pointer<non_pointer>::value)
 | 
			
		||||
   value_test(false, is_pointer<int*&>::value)
 | 
			
		||||
   value_test(false, is_pointer<int(&)[2]>::value)
 | 
			
		||||
   value_test(false, is_pointer<int[2]>::value)
 | 
			
		||||
   value_test(false, is_pointer<char[sizeof(void*)]>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, is_pointer<f1>::value)
 | 
			
		||||
   value_test(true, is_pointer<f2>::value)
 | 
			
		||||
   value_test(true, is_pointer<f3>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9.2p3
 | 
			
		||||
   value_test(false, is_pointer<mf1>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9.2p3
 | 
			
		||||
   value_test(false, is_pointer<mf2>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9.2p3
 | 
			
		||||
   value_test(false, is_pointer<mf3>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9.2p3
 | 
			
		||||
   value_test(false, is_pointer<mf4>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_reference<bool>::value)
 | 
			
		||||
   value_test(true, is_reference<int&>::value)
 | 
			
		||||
   value_test(true, is_reference<const int&>::value)
 | 
			
		||||
   value_test(true, is_reference<volatile int &>::value)
 | 
			
		||||
   value_test(true, is_reference<r_type>::value)
 | 
			
		||||
   value_test(true, is_reference<cr_type>::value)
 | 
			
		||||
   value_test(true, is_reference<const UDT&>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_class<int>::value)
 | 
			
		||||
   value_test(false, is_class<const int>::value)
 | 
			
		||||
   value_test(false, is_class<volatile int>::value)
 | 
			
		||||
   value_test(false, is_class<int*>::value)
 | 
			
		||||
   value_test(false, is_class<int* const>::value)
 | 
			
		||||
   value_test(false, is_class<int[2]>::value)
 | 
			
		||||
   value_test(false, is_class<int&>::value)
 | 
			
		||||
   value_test(false, is_class<mf4>::value)
 | 
			
		||||
   value_test(false, is_class<f1>::value)
 | 
			
		||||
   value_test(false, is_class<enum_UDT>::value)
 | 
			
		||||
   value_test(true, is_class<UDT>::value)
 | 
			
		||||
   value_test(true, is_class<UDT const>::value)
 | 
			
		||||
   value_test(true, is_class<UDT volatile>::value)
 | 
			
		||||
   value_test(true, is_class<empty_UDT>::value)
 | 
			
		||||
   value_test(true, is_class<std::iostream>::value)
 | 
			
		||||
   value_test(false, is_class<UDT*>::value)
 | 
			
		||||
   value_test(false, is_class<UDT[2]>::value)
 | 
			
		||||
   value_test(false, is_class<UDT&>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, is_object<int>::value)
 | 
			
		||||
   value_test(true, is_object<UDT>::value)
 | 
			
		||||
   value_test(false, is_object<int&>::value)
 | 
			
		||||
   value_test(false, is_object<void>::value)
 | 
			
		||||
   value_test(true, is_standard_scalar<int>::value)
 | 
			
		||||
   value_test(true, is_extension_scalar<void*>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_enum<int>::value)
 | 
			
		||||
   value_test(true, is_enum<enum_UDT>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_member_pointer<f1>::value)
 | 
			
		||||
   value_test(false, is_member_pointer<f2>::value)
 | 
			
		||||
   value_test(false, is_member_pointer<f3>::value)
 | 
			
		||||
   value_test(true, is_member_pointer<mf1>::value)
 | 
			
		||||
   value_test(true, is_member_pointer<mf2>::value)
 | 
			
		||||
   value_test(true, is_member_pointer<mf3>::value)
 | 
			
		||||
   value_test(true, is_member_pointer<mf4>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(false, is_empty<int>::value)
 | 
			
		||||
   value_test(false, is_empty<int*>::value)
 | 
			
		||||
   value_test(false, is_empty<int&>::value)
 | 
			
		||||
#if defined(__MWERKS__) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 | 
			
		||||
   // apparent compiler bug causes this to fail to compile:
 | 
			
		||||
   value_fail(false, is_empty<int[2]>::value)
 | 
			
		||||
#else
 | 
			
		||||
   value_test(false, is_empty<int[2]>::value)
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 | 
			
		||||
   value_fail(false, is_empty<f1>::value)
 | 
			
		||||
#else
 | 
			
		||||
   value_test(false, is_empty<f1>::value)
 | 
			
		||||
#endif
 | 
			
		||||
   value_test(false, is_empty<mf1>::value)
 | 
			
		||||
   value_test(false, is_empty<UDT>::value)
 | 
			
		||||
   value_test(true, is_empty<empty_UDT>::value)
 | 
			
		||||
   value_test(true, is_empty<empty_POD_UDT>::value)
 | 
			
		||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 | 
			
		||||
   value_fail(true, is_empty<empty_union_UDT>::value)
 | 
			
		||||
#else
 | 
			
		||||
   value_test(true, is_empty<empty_union_UDT>::value)
 | 
			
		||||
#endif
 | 
			
		||||
   value_test(false, is_empty<enum_UDT>::value)
 | 
			
		||||
   value_test(true, is_empty<boost::noncopyable>::value)
 | 
			
		||||
   value_test(false, is_empty<non_empty>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, has_trivial_constructor<int>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<int*>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<int*const>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<const int>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<volatile int>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<int[2]>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<int[3][2]>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<int[2][4][5][6][3]>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<f1>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<mf2>::value)
 | 
			
		||||
   value_test(false, has_trivial_constructor<UDT>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<empty_UDT>::value)
 | 
			
		||||
   value_test(true, has_trivial_constructor<enum_UDT>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, has_trivial_copy<int>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<int*>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<int*const>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<const int>::value)
 | 
			
		||||
   // Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
 | 
			
		||||
   value_test(true, has_trivial_copy<volatile int>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<int[2]>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<int[3][2]>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<int[2][4][5][6][3]>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<f1>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<mf2>::value)
 | 
			
		||||
   value_test(false, has_trivial_copy<UDT>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<empty_UDT>::value)
 | 
			
		||||
   value_test(true, has_trivial_copy<enum_UDT>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, has_trivial_assign<int>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<int*>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<int*const>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<const int>::value)
 | 
			
		||||
   // Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
 | 
			
		||||
   value_test(true, has_trivial_assign<volatile int>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<int[2]>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<int[3][2]>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<int[2][4][5][6][3]>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<f1>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<mf2>::value)
 | 
			
		||||
   value_test(false, has_trivial_assign<UDT>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<empty_UDT>::value)
 | 
			
		||||
   value_test(true, has_trivial_assign<enum_UDT>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, has_trivial_destructor<int>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<int*>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<int*const>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<const int>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<volatile int>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<int[2]>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<int[3][2]>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<int[2][4][5][6][3]>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<f1>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<mf2>::value)
 | 
			
		||||
   value_test(false, has_trivial_destructor<UDT>::value)
 | 
			
		||||
   value_test(false, has_trivial_destructor<empty_UDT>::value)
 | 
			
		||||
   value_test(true, has_trivial_destructor<enum_UDT>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, is_POD<int>::value)
 | 
			
		||||
   value_test(true, is_POD<int*>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9p10
 | 
			
		||||
   value_test(false, is_POD<int&>::value)
 | 
			
		||||
   value_test(true, is_POD<int*const>::value)
 | 
			
		||||
   value_test(true, is_POD<const int>::value)
 | 
			
		||||
   // Steve: was 'false', should be 'true', via 3.9p10
 | 
			
		||||
   value_test(true, is_POD<volatile int>::value)
 | 
			
		||||
   // Steve: was 'true', should be 'false', via 3.9p10
 | 
			
		||||
   value_test(false, is_POD<const int&>::value)
 | 
			
		||||
   value_test(true, is_POD<int[2]>::value)
 | 
			
		||||
   value_test(true, is_POD<int[3][2]>::value)
 | 
			
		||||
   value_test(true, is_POD<int[2][4][5][6][3]>::value)
 | 
			
		||||
   value_test(true, is_POD<f1>::value)
 | 
			
		||||
   value_test(true, is_POD<mf2>::value)
 | 
			
		||||
   value_test(false, is_POD<UDT>::value)
 | 
			
		||||
   value_test(false, is_POD<empty_UDT>::value)
 | 
			
		||||
   value_test(true, is_POD<enum_UDT>::value)
 | 
			
		||||
 | 
			
		||||
   value_test(true, (boost::is_convertible<Deriverd,Base>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<Base,Base>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<Base,Deriverd>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<NonDerived,Base>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<boost::noncopyable, int>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<float,int>::value));
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 | 
			
		||||
   value_test(false, (boost::is_convertible<float,void>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<void,float>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<void,void>::value));
 | 
			
		||||
#endif
 | 
			
		||||
   value_test(true, (boost::is_convertible<enum1, int>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<Deriverd*, Base*>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<Base*, Deriverd*>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<Deriverd&, Base&>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<Base&, Deriverd&>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<const Deriverd*, const Base*>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<const Base*, const Deriverd*>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<const Deriverd&, const Base&>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<const Base&, const Deriverd&>::value));
 | 
			
		||||
 | 
			
		||||
   value_test(false, (boost::is_convertible<const int *, int*>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<const int&, int&>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<int*, int[2]>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<const int*, int[3]>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<const int&, int>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<int(&)[4], const int*>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<int(&)(int), int(*)(int)>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<int *, const int*>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<int&, const int&>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<int[2], int*>::value));
 | 
			
		||||
   value_test(true, (boost::is_convertible<int[2], const int*>::value));
 | 
			
		||||
   value_test(false, (boost::is_convertible<const int[2], int*>::value));
 | 
			
		||||
 | 
			
		||||
   align_test(int);
 | 
			
		||||
   align_test(char);
 | 
			
		||||
   align_test(double);
 | 
			
		||||
   align_test(int[4]);
 | 
			
		||||
   align_test(int(*)(int));
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
   align_test(char&);
 | 
			
		||||
   align_test(char (&)(int));
 | 
			
		||||
   align_test(char(&)[4]);
 | 
			
		||||
#endif
 | 
			
		||||
   align_test(int*);
 | 
			
		||||
   //align_test(const int);
 | 
			
		||||
   align_test(VB);
 | 
			
		||||
   align_test(VD);
 | 
			
		||||
 | 
			
		||||
   std::cout << std::endl << test_count << " tests completed (" << failures << " failures)";
 | 
			
		||||
   return failures;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										194
									
								
								utility.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								utility.htm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
			
		||||
<html>
 | 
			
		||||
	<head>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
		<title>Header boost/utility.hpp Documentation</title>
 | 
			
		||||
	</head>
 | 
			
		||||
	<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
		<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
 | 
			
		||||
			<a href="../../boost/utility.hpp">boost/utility.hpp</a></h1>
 | 
			
		||||
		<p>The entire contents of the header <code><a href="../../boost/utility.hpp"><boost/utility.hpp></a></code>
 | 
			
		||||
			are in <code>namespace boost</code>.</p>
 | 
			
		||||
		<h2>Contents</h2>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li>
 | 
			
		||||
				Class templates supporting the <a href="base_from_member.html">base-from-member 
 | 
			
		||||
					idiom</a></li>
 | 
			
		||||
			<li>
 | 
			
		||||
				Function templates <a href="#checked_delete">checked_delete() and 
 | 
			
		||||
					checked_array_delete()</a></li>
 | 
			
		||||
			<li>
 | 
			
		||||
				Function templates <a href="#functions_next_prior">next() and prior()</a></li>
 | 
			
		||||
			<li>
 | 
			
		||||
				Class <a href="#Class_noncopyable">noncopyable</a></li>
 | 
			
		||||
			<li>
 | 
			
		||||
				Function template <a href="#addressof">addressof()</a></li>
 | 
			
		||||
                        <li>Class template <a href="#result_of">result_of</a></li>
 | 
			
		||||
                        <li><a href="index.html">Other utilities not part of <code>utility.hpp</code></a></li>
 | 
			
		||||
		</ul>
 | 
			
		||||
		<h2>
 | 
			
		||||
			Function templates <a name="checked_delete">checked_delete</a>() and 
 | 
			
		||||
			checked_array_delete()</h2>
 | 
			
		||||
		<p>See <a href="checked_delete.html">separate documentation</a>.</p>
 | 
			
		||||
		<h2>
 | 
			
		||||
			<a name="functions_next_prior">Function</a> templates next() and prior()</h2>
 | 
			
		||||
		<p>Certain data types, such as the C++ Standard Library's forward and bidirectional 
 | 
			
		||||
			iterators, do not provide addition and subtraction via operator+() or 
 | 
			
		||||
			operator-().  This means that non-modifying computation of the next or 
 | 
			
		||||
			prior value requires a temporary, even though operator++() or operator--() is 
 | 
			
		||||
			provided.  It also means that writing code like <code>itr+1</code> inside 
 | 
			
		||||
			a template restricts the iterator category to random access iterators.</p>
 | 
			
		||||
		<p>The next() and prior() functions provide a simple way around these problems:</p>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<pre>template <class T>
 | 
			
		||||
T next(T x) { return ++x; }
 | 
			
		||||
 | 
			
		||||
template <class T, class Distance>
 | 
			
		||||
T next(T x, Distance n)
 | 
			
		||||
{
 | 
			
		||||
    std::advance(x, n);
 | 
			
		||||
    return x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
T prior(T x) { return --x; }
 | 
			
		||||
 | 
			
		||||
template <class T, class Distance>
 | 
			
		||||
T prior(T x, Distance n)
 | 
			
		||||
{
 | 
			
		||||
    std::advance(x, -n);
 | 
			
		||||
    return x;
 | 
			
		||||
}</pre>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<p>Usage is simple:</p>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<pre>const std::list<T>::iterator p = get_some_iterator();
 | 
			
		||||
const std::list<T>::iterator prev = boost::prior(p);
 | 
			
		||||
const std::list<T>::iterator next = boost::next(prev, 2);</pre>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
                <p>The distance from the given iterator should be supplied as an absolute value. For
 | 
			
		||||
			example, the iterator four iterators prior to the given iterator <code>p</code>
 | 
			
		||||
			may be obtained by <code>prior(p, 4)</code>.</p>
 | 
			
		||||
		<p>Contributed by <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.  Two-argument versions by Daniel Walker.</p>
 | 
			
		||||
		<h2><a name="Class_noncopyable">Class noncopyable</a></h2>
 | 
			
		||||
		<p>Class <strong>noncopyable</strong> is a base class.  Derive your own class 
 | 
			
		||||
			from <strong>noncopyable</strong> when you want to prohibit copy construction 
 | 
			
		||||
			and copy assignment.</p>
 | 
			
		||||
		<p>Some objects, particularly those which hold complex resources like files or 
 | 
			
		||||
			network connections, have no sensible copy semantics.  Sometimes there are 
 | 
			
		||||
			possible copy semantics, but these would be of very limited usefulness and be 
 | 
			
		||||
			very difficult to implement correctly.  Sometimes you're implementing a 
 | 
			
		||||
			class that doesn't need to be copied just yet and you don't want to take the 
 | 
			
		||||
			time to write the appropriate functions.  Deriving from <b>noncopyable</b> 
 | 
			
		||||
			will prevent the otherwise implicitly-generated functions (which don't have the 
 | 
			
		||||
			proper semantics) from becoming a trap for other programmers.</p>
 | 
			
		||||
		<p>The traditional way to deal with these is to declare a private copy constructor 
 | 
			
		||||
			and copy assignment, and then document why this is done.  But deriving 
 | 
			
		||||
			from <b>noncopyable</b> is simpler and clearer, and doesn't require additional 
 | 
			
		||||
			documentation.</p>
 | 
			
		||||
		<p>The program <a href="noncopyable_test.cpp">noncopyable_test.cpp</a> can be used 
 | 
			
		||||
			to verify class <b>noncopyable</b> works as expected. It has have been run 
 | 
			
		||||
			successfully under GCC 2.95, Metrowerks CodeWarrior 5.0, and Microsoft Visual 
 | 
			
		||||
			C++ 6.0 sp 3.</p>
 | 
			
		||||
		<p>Contributed by <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.</p>
 | 
			
		||||
		<h3>Example</h3>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<pre>// inside one of your own headers ...
 | 
			
		||||
#include <boost/utility.hpp>
 | 
			
		||||
 | 
			
		||||
class ResourceLadenFileSystem : boost::noncopyable {
 | 
			
		||||
...</pre>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3>Rationale</h3>
 | 
			
		||||
		<p>Class noncopyable has protected constructor and destructor members to emphasize 
 | 
			
		||||
			that it is to be used only as a base class.  Dave Abrahams notes concern 
 | 
			
		||||
			about the effect on compiler optimization of adding (even trivial inline) 
 | 
			
		||||
			destructor declarations. He says "Probably this concern is misplaced, 
 | 
			
		||||
			because noncopyable will be used mostly for classes which own resources and 
 | 
			
		||||
			thus have non-trivial destruction semantics."</p>
 | 
			
		||||
		<h2><a name="addressof">Function template addressof()</a></h2>
 | 
			
		||||
		<p>Function <strong>addressof()</strong> returns the address of an object.</p>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<pre>template <typename T> inline T*                addressof(T& v);
 | 
			
		||||
template <typename T> inline const T*          addressof(const T& v);
 | 
			
		||||
template <typename T> inline volatile T*       addressof(volatile T& v);
 | 
			
		||||
template <typename T> inline const volatile T* addressof(const volatile T& v);
 | 
			
		||||
</pre>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<p>C++ allows programmers to replace the unary <strong>operator&()</strong> class 
 | 
			
		||||
			member used to get the address of an object. Getting the real address of an 
 | 
			
		||||
			object requires ugly casting tricks to avoid invoking the overloaded <strong>operator&()</strong>. 
 | 
			
		||||
			Function <strong>addressof()</strong> provides a wrapper around the necessary 
 | 
			
		||||
			code to make it easy to get an object's real address.
 | 
			
		||||
		</p>
 | 
			
		||||
		<p>The program <a href="addressof_test.cpp">addressof_test.cpp</a> can be used to 
 | 
			
		||||
			verify that <b>addressof()</b> works as expected.</p>
 | 
			
		||||
		<p>Contributed by Brad King based on ideas from discussion with Doug Gregor.</p>
 | 
			
		||||
		<h3>Example</h3>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<pre>#include <boost/utility.hpp>
 | 
			
		||||
 | 
			
		||||
struct useless_type {};
 | 
			
		||||
class nonaddressable {
 | 
			
		||||
  useless_type operator&() const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void f() {
 | 
			
		||||
  nonaddressable x;
 | 
			
		||||
  nonaddressable* xp = boost::addressof(x);
 | 
			
		||||
  // nonaddressable* xpe = &x; /* error */
 | 
			
		||||
}</pre>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
                <h2><a name="result_of">Class template
 | 
			
		||||
                result_of</a></h2> <p>The class template
 | 
			
		||||
                <code>result_of</code> helps determine the type of a
 | 
			
		||||
                call expression. Given an lvalue <code>f</code> of
 | 
			
		||||
                type <code>F</code> and lvalues <code>t1</code>,
 | 
			
		||||
                <code>t2</code>, ..., <code>t<em>N</em></code> of
 | 
			
		||||
                types <code>T1</code>, <code>T2</code>, ...,
 | 
			
		||||
                <code>T<em>N</em></code>, respectively, the type
 | 
			
		||||
                <code>result_of<F(T1, T2, ...,
 | 
			
		||||
                T<em>N</em>)>::type</code> defines the result type
 | 
			
		||||
                of the expression <code>f(t1, t2,
 | 
			
		||||
                ...,t<em>N</em>)</code>. The implementation permits
 | 
			
		||||
                the type <code>F</code> to be a function pointer,
 | 
			
		||||
                function reference, member function pointer, or class
 | 
			
		||||
                type. When <code>F</code> is a class type with a
 | 
			
		||||
                member type <code>result_type</code>,
 | 
			
		||||
                <code>result_of<F(T1, T2, ...,
 | 
			
		||||
                T<em>N</em>)></code> is
 | 
			
		||||
                <code>F::result_type</code>. Otherwise,
 | 
			
		||||
                <code>result_of<F(T1, T2, ...,
 | 
			
		||||
                T<em>N</em>)></code> is <code>F::result<F(T1,
 | 
			
		||||
                T2, ..., T<em>N</em>)>::type</code> when
 | 
			
		||||
                <code><em>N</em> > 0</code> or <code>void</code>
 | 
			
		||||
                when <code><em>N</em> = 0</code>. For additional
 | 
			
		||||
                information about <code>result_of</code>, see the
 | 
			
		||||
                C++ Library Technical Report, <a
 | 
			
		||||
                href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
 | 
			
		||||
                or, for motivation and design rationale, the <code>result_of</code> <a
 | 
			
		||||
                href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
 | 
			
		||||
 | 
			
		||||
                <p>Class template <code>result_of</code> resides in
 | 
			
		||||
                the header <code><<a
 | 
			
		||||
                href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>. By
 | 
			
		||||
                default, <em>N</em> may be any value between 0 and
 | 
			
		||||
                10. To change the upper limit, define the macro
 | 
			
		||||
                <code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
 | 
			
		||||
                value for <em>N</em>.</p>
 | 
			
		||||
 | 
			
		||||
                <a name="BOOST_NO_RESULT_OF"></a>
 | 
			
		||||
                <p>This implementation of <code>result_of</code> requires class template partial specialization, the ability to parse function types properly, and support for SFINAE. If <code>result_of</code> is not supported by your compiler, including the header <code>boost/utility/result_of.hpp</code> will define the macro <code>BOOST_NO_RESULT_OF</code>. Contributed by Doug Gregor.</p>
 | 
			
		||||
 | 
			
		||||
		<h2>Class templates for the Base-from-Member Idiom</h2>
 | 
			
		||||
		<p>See <a href="base_from_member.html">separate documentation</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="39369"
 | 
			
		||||
-->
 | 
			
		||||
		</p>
 | 
			
		||||
		<p>© Copyright Beman Dawes 1999-2003.</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>
 | 
			
		||||
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										388
									
								
								value_init.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								value_init.htm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,388 @@
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
             
 | 
			
		||||
  <meta http-equiv="Content-Type"
 | 
			
		||||
 content="text/html; charset=iso-8859-1">
 | 
			
		||||
  <title>value_initialized</title>
 | 
			
		||||
    
 | 
			
		||||
</head>
 | 
			
		||||
  <body vlink="#800080" link="#0000ff" text="#000000" bgcolor="#ffffff">
 | 
			
		||||
                   
 | 
			
		||||
<h2><img src="../../boost.png" width="276" height="86">
 | 
			
		||||
         Header <<a href="../../boost/utility/value_init.hpp">boost/utility/value_init.hpp</a>>
 | 
			
		||||
     </h2>
 | 
			
		||||
                   
 | 
			
		||||
<h2>Contents</h2>
 | 
			
		||||
                   
 | 
			
		||||
<dl>
 | 
			
		||||
  <dt><a href="#rationale">Rationale</a></dt>
 | 
			
		||||
  <dt><a href="#intro">Introduction</a></dt>
 | 
			
		||||
  <dt><a href="#details">Details</a></dt>
 | 
			
		||||
</dl>
 | 
			
		||||
                   
 | 
			
		||||
<ul>
 | 
			
		||||
          <li><a href="#valueinit">value-initialization</a></li>
 | 
			
		||||
          <li><a href="#valueinitsyn">value-initialization syntax</a></li>
 | 
			
		||||
          <li><a href="#compiler_issues">compiler issues</a></li>
 | 
			
		||||
                   
 | 
			
		||||
</ul>
 | 
			
		||||
                   
 | 
			
		||||
<dl class="page-index">
 | 
			
		||||
  <dt><a href="#types">Types</a></dt>
 | 
			
		||||
</dl>
 | 
			
		||||
                   
 | 
			
		||||
<ul>
 | 
			
		||||
          <li><a href="#val_init"><code>template class value_initialized<T></code></a></li>
 | 
			
		||||
          <li><a href="#initialized_value"><code>class initialized_value</code></a></li>
 | 
			
		||||
                   
 | 
			
		||||
</ul>
 | 
			
		||||
              <a href="#acknowledgements">Acknowledgements</a><br>
 | 
			
		||||
     <br>
 | 
			
		||||
         
 | 
			
		||||
<hr>          
 | 
			
		||||
<h2><a name="rationale"></a>Rationale</h2>
 | 
			
		||||
                  
 | 
			
		||||
<p>Constructing and initializing objects in a generic way is difficult in
 | 
			
		||||
    C++. The problem is that there are several different rules that apply
 | 
			
		||||
for    initialization. Depending on the type, the value of a newly constructed
 | 
			
		||||
  object  can be zero-initialized (logically 0), default-constructed (using
 | 
			
		||||
  the default constructor), or indeterminate. When writing generic code,
 | 
			
		||||
this  problem must be addressed. The template <code>value_initialized</code> provides
 | 
			
		||||
a solution   with consistent syntax for value   initialization of scalar,
 | 
			
		||||
union and class   types.
 | 
			
		||||
Moreover, <code>value_initialized</code> offers a workaround to various
 | 
			
		||||
compiler issues regarding value-initialization.
 | 
			
		||||
 | 
			
		||||
Furthermore a convenience class, <code>initialized_value</code> is provided,
 | 
			
		||||
to avoid repeating the type name when retrieving the value from a
 | 
			
		||||
<code>value_initialized<T></code> object.
 | 
			
		||||
<br>
 | 
			
		||||
  </p>
 | 
			
		||||
        
 | 
			
		||||
<h2><a name="intro"></a>Introduction</h2>
 | 
			
		||||
     
 | 
			
		||||
<p>
 | 
			
		||||
There are various ways to initialize a variable, in C++. The following
 | 
			
		||||
declarations all <em>may</em> have a local variable initialized to its default
 | 
			
		||||
value:
 | 
			
		||||
<pre>
 | 
			
		||||
  T1 var1;
 | 
			
		||||
  T2 var2 = 0;
 | 
			
		||||
  T3 var3 = {};
 | 
			
		||||
  T4 var4 = T4();
 | 
			
		||||
</pre> 
 | 
			
		||||
Unfortunately, whether or not any of those declarations correctly
 | 
			
		||||
initialize the variable very much depends on its type. The first
 | 
			
		||||
declaration is valid for any <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
 | 
			
		||||
DefaultConstructible</a> type (by definition).
 | 
			
		||||
However, it does not always do an initialization!
 | 
			
		||||
It correctly initializes the variable when it's an instance of a
 | 
			
		||||
class, and the author of the class has provided a proper default
 | 
			
		||||
constructor. On the other hand, the value of <code>var1</code> is <em>indeterminate</em> when
 | 
			
		||||
its type is an arithmetic type, like <code>int</code>, <code>float</code>, or <code>char</code>.
 | 
			
		||||
An arithmetic variable
 | 
			
		||||
is of course initialized properly by the second declaration, <code>T2
 | 
			
		||||
var2 = 0</code>. But this initialization form usually won't work for a
 | 
			
		||||
class type (unless the class was especially written to support being
 | 
			
		||||
initialized that way). The third form,  <code>T3 var3 = {}</code>
 | 
			
		||||
initializes an aggregate, typically a "C-style" <code>struct</code> or a "C-style" array.
 | 
			
		||||
However, the syntax is not allowed for a class that has an explicitly declared
 | 
			
		||||
constructor.  (But watch out for an upcoming C++ language change, 
 | 
			
		||||
by Bjarne Stroustrup et al [<a href="#references">1</a>]!)
 | 
			
		||||
The fourth form is the most generic form of them, as it
 | 
			
		||||
can be used to initialize arithmetic types, class types, aggregates, pointers, and
 | 
			
		||||
other types. The declaration,  <code>T4 var4 = T4()</code>, should be read
 | 
			
		||||
as follows: First a temporary object is created, by <code>T4()</code>.
 | 
			
		||||
This object is <a href="#valueinit">value-initialized</a>. Next the temporary
 | 
			
		||||
object is copied to the named variable, <code>var4</code>. Afterwards, the temporary
 | 
			
		||||
is destroyed. While the copying and the destruction are likely to
 | 
			
		||||
be optimized away, C++ still requires the type <code>T4</code> to be
 | 
			
		||||
<a href="CopyConstructible.html">CopyConstructible</a>.
 | 
			
		||||
(So <code>T4</code> needs to be <em>both</em> DefaultConstructible <em>and</em> CopyConstructible.) 
 | 
			
		||||
A class may not be CopyConstructible, for example because it may have a
 | 
			
		||||
private and undefined copy constructor,
 | 
			
		||||
or because it may be derived from <a href="utility.htm#Class_noncopyable">boost::noncopyable</a>.
 | 
			
		||||
Scott Meyers [<a href="#references">2</a>] explains why a class would be defined like that.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
There is another, less obvious disadvantage to the fourth form, <code>T4 var4 = T4()</code>:
 | 
			
		||||
It suffers from various  <a href="#compiler_issues">compiler issues</a>, causing
 | 
			
		||||
a variable to be left uninitialized in some compiler specific cases.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
The template <a href="#val_init"><code>value_initialized</code></a>
 | 
			
		||||
offers a generic way to initialize
 | 
			
		||||
an object, like <code>T4 var4 = T4()</code>, but without requiring its type
 | 
			
		||||
to be CopyConstructible. And it offers a workaround to those compiler issues
 | 
			
		||||
regarding value-initialization as well! It allows getting an initialized
 | 
			
		||||
variable of any type; it <em>only</em> requires the type to be DefaultConstructible.
 | 
			
		||||
A properly <em>value-initialized</em> object of type <code>T</code> is
 | 
			
		||||
constructed by the following declaration:
 | 
			
		||||
<pre>
 | 
			
		||||
  value_initialized<T> var;
 | 
			
		||||
</pre>
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
The convenience class <a href="#initialized_value"><code>initialized_value</code></a>
 | 
			
		||||
allows value-initializing a variable as follows:
 | 
			
		||||
<pre>
 | 
			
		||||
  T var = initialized_value();
 | 
			
		||||
</pre>
 | 
			
		||||
This form of initialization is also very similar to <code>T4 var4 = T4()</code>,
 | 
			
		||||
but robust against the aforementioned compiler issues.
 | 
			
		||||
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
<h2><a name="details"></a>Details</h2>
 | 
			
		||||
<p>The C++ standard [<a href="#references">3</a>] contains the definitions 
 | 
			
		||||
    of <code>zero-initialization</code> and <code>default-initialization</code>.
 | 
			
		||||
     Informally, zero-initialization means that the object is given the initial
 | 
			
		||||
     value 0 (converted to the type) and default-initialization means that
 | 
			
		||||
 POD   [<a href="#references">4</a>] types are zero-initialized, while non-POD class
 | 
			
		||||
 types   are initialized with their corresponding default constructors. A
 | 
			
		||||
<i>declaration</i>   can contain an <i>initializer</i>, which specifies the
 | 
			
		||||
object's initial value.  The initializer can be just '()', which states that
 | 
			
		||||
the object shall be value-initialized  (but see below). However, if a <i>declaration</i> 
 | 
			
		||||
  has no <i>initializer</i>  and it is of a non-<code>const</code>, non-<code>static</code> 
 | 
			
		||||
   POD type, the initial value is indeterminate: <cite>(see §8.5, [dcl.init], for the
 | 
			
		||||
   accurate definitions).</cite></p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>int x ; // no initializer. x value is indeterminate.<br>std::string s ; // no initializer, s is default-constructed.<br><br>int y = int() ; <br>// y is initialized using copy-initialization<br>// but the temporary uses an empty set of parentheses as the initializer,<br>// so it is default-constructed.<br>// A default constructed POD type is zero-initialized,<br>// therefore, y == 0.<br><br>void foo ( std::string ) ;<br>foo ( std::string() ) ; <br>// the temporary string is default constructed <br>// as indicated by the initializer ()  </pre>
 | 
			
		||||
                    
 | 
			
		||||
<h3><a name="valueinit">value-initialization</a></h3>
 | 
			
		||||
                   
 | 
			
		||||
<p>The first <a
 | 
			
		||||
 href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_defects.html">Technical 
 | 
			
		||||
  Corrigendum for the C++ Standard</a> (TC1), whose draft   was released to
 | 
			
		||||
  the public in November 2001, introduced <a
 | 
			
		||||
 href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_defects.html#178">Core 
 | 
			
		||||
  Issue 178</a> (among   many other issues, of course).</p>
 | 
			
		||||
                   
 | 
			
		||||
<p> That issue introduced the new concept of <code>value-initialization</code>
 | 
			
		||||
     (it also fixed the wording for zero-initialization). Informally, value-initialization 
 | 
			
		||||
    is similar to default-initialization with the exception that in some cases
 | 
			
		||||
    non-static data members and base class sub-objects are also value-initialized. 
 | 
			
		||||
    The difference is that an object that is value-initialized won't have 
 | 
			
		||||
(or    at least is less likely to have) indeterminate values for data members 
 | 
			
		||||
 and   base class sub-objects; unlike the case of an object default constructed. 
 | 
			
		||||
    (see Core Issue 178 for a normative description).</p>
 | 
			
		||||
                   
 | 
			
		||||
<p>In order to specify value-initialization of an object we need to use the
 | 
			
		||||
     empty-set initializer: (). </p>
 | 
			
		||||
                   
 | 
			
		||||
<p>As before, a declaration with no intializer specifies default-initialization, 
 | 
			
		||||
    and a declaration with a non-empty initializer specifies copy (=xxx) or
 | 
			
		||||
  direct  (xxx) initialization. </p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>template<class T> void eat(T);<br>int x ; // indeterminate initial value.<br>std::string s; // default-initialized.<br>eat ( int() ) ; // value-initialized<br>eat ( std::string() ) ; // value-initialized</pre>
 | 
			
		||||
                    
 | 
			
		||||
<h4><a name="valueinitsyn">value-initialization</a> syntax</h4>
 | 
			
		||||
                   
 | 
			
		||||
<p>Value initialization is specified using (). However, the empty set of
 | 
			
		||||
parentheses is not permitted by the syntax of initializers because it is
 | 
			
		||||
parsed as the declaration of a function taking no arguments: </p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>int x() ; // declares function int(*)()</pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>Thus, the empty () must be put in some other initialization context.</p>
 | 
			
		||||
                   
 | 
			
		||||
<p>One alternative is to use copy-initialization syntax:</p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>int x = int() ;</pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>This works perfectly fine for POD types. But for non-POD class types,
 | 
			
		||||
copy-initialization searches for a suitable constructor, which could be,
 | 
			
		||||
for instance, the copy-constructor (it also searches for a suitable conversion
 | 
			
		||||
sequence but this doesn't apply in this context). For an arbitrary unknown
 | 
			
		||||
type, using this syntax may not have the value-initialization effect intended
 | 
			
		||||
because we don't know if a copy from a default constructed object is exactly
 | 
			
		||||
the same as a default constructed object, and the compiler is allowed (in
 | 
			
		||||
some cases), but never required to, optimize the copy away.</p>
 | 
			
		||||
                   
 | 
			
		||||
<p>One possible generic solution is to use value-initialization of a non static
 | 
			
		||||
data member:</p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>template<class T> <br>struct W <br>{<br>  // value-initialization of 'data' here.<br>  W() : data() {}<br>  T data ;<br>} ;<br>W<int> w ;<br>// w.data is value-initialized for any type. </pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>This is the solution as it was supplied by earlier versions of the
 | 
			
		||||
<code>value_initialized<T></code> template
 | 
			
		||||
     class. Unfortunately this approach suffered from various compiler issues.</p>
 | 
			
		||||
		 
 | 
			
		||||
<h4><a name="compiler_issues">compiler issues</a> </h4>
 | 
			
		||||
 | 
			
		||||
Various compilers haven't yet fully implemented value-initialization.
 | 
			
		||||
So when an object should be <em>value-initialized</em> (according to the C++ Standard),
 | 
			
		||||
it <em>may</em> in practice still be left uninitialized, because of those
 | 
			
		||||
compiler issues! It's hard to make a general statement on what those issues
 | 
			
		||||
are like, because they depend on the compiler you are using, its version number,
 | 
			
		||||
and the type of object you would like to have value-initialized.
 | 
			
		||||
Compilers usually support value-initialization for built-in types properly.
 | 
			
		||||
But objects of user-defined types that involve <em>aggregates</em> may <em>in some cases</em>
 | 
			
		||||
be partially, or even entirely left uninitialized, when they should be value-initialized.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
We have encountered issues regarding value-initialization on compilers by
 | 
			
		||||
Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues:
 | 
			
		||||
<table summary="Compiler bug reports regarding value-initialization" border="0" cellpadding="7" cellspacing="1" >
 | 
			
		||||
<tr><td>
 | 
			
		||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744">
 | 
			
		||||
Microsoft Feedback ID 100744 - Value-initialization in new-expression</a>
 | 
			
		||||
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28
 | 
			
		||||
<br>
 | 
			
		||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">
 | 
			
		||||
GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members</a>
 | 
			
		||||
<br>Reported by Jonathan Wakely, 2006-12-07 
 | 
			
		||||
<br>
 | 
			
		||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916">
 | 
			
		||||
GCC Bug 33916 - Default constructor fails to initialize array members</a>
 | 
			
		||||
<br>Reported by Michael Elizabeth Chastain, 2007-10-26
 | 
			
		||||
<br>
 | 
			
		||||
<a href="http://qc.codegear.com/wc/qcmain.aspx?d=51854">
 | 
			
		||||
Borland Report 51854 - Value-initialization: POD struct should be zero-initialized</a>
 | 
			
		||||
<br>Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11
 | 
			
		||||
<br>
 | 
			
		||||
</td></tr></table>
 | 
			
		||||
</p><p>
 | 
			
		||||
New versions of <code>value_initialized</code>
 | 
			
		||||
(Boost release version 1.35 or higher)
 | 
			
		||||
offer a workaround to these issues: <code>value_initialized</code> will now clear
 | 
			
		||||
its internal data, prior to constructing the object that it contains.
 | 
			
		||||
</p>
 | 
			
		||||
                   
 | 
			
		||||
<h2><a name="types"></a>Types</h2>
 | 
			
		||||
                   
 | 
			
		||||
<h2><a name="val_init"><code>template class value_initialized<T></code></a></h2>
 | 
			
		||||
                   
 | 
			
		||||
<pre>namespace boost {<br><br>template<class T><br>class value_initialized<br>{<br>  public :<br>    value_initialized() : x() {}<br>    operator T&() const { return x ; }<br>    T& data() const { return x ; }<br><br>  private :<br>    <i>unspecified</i> x ;<br>} ;<br><br>template<class T><br>T const& get ( value_initialized<T> const& x )<br>{<br>  return x.data() ;<br>}<br><br>template<class T><br>T& get ( value_initialized<T>& x )<br>{<br>  return x.data() ;<br>}<br><br>} // namespace boost<br></pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>An object of this template class is a <code>T</code>-wrapper convertible 
 | 
			
		||||
    to <code>'T&'</code> whose wrapped object (data member of type <code>T</code>) 
 | 
			
		||||
    is <a href="#valueinit">value-initialized</a> upon default-initialization 
 | 
			
		||||
    of this wrapper class: </p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>int zero = 0 ;<br>value_initialized<int> x ;<br>assert ( x == zero ) ;<br><br>std::string def ;<br>value_initialized< std::string > y ;<br>assert ( y == def ) ;<br></pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>The purpose of this wrapper is to provide a consistent syntax for value
 | 
			
		||||
     initialization of scalar, union and class types (POD and non-POD) since
 | 
			
		||||
   the  correct syntax for value initialization varies (see <a
 | 
			
		||||
 href="#valueinitsyn">value-initialization syntax</a>)</p>
 | 
			
		||||
                   
 | 
			
		||||
<p>The wrapped object can be accessed either through the conversion operator
 | 
			
		||||
     <code>T&</code>, the member function <code>data()</code>, or the
 | 
			
		||||
non-member    function <code>get()</code>:  </p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>void watch(int);<br>value_initialized<int> x;<br><br>watch(x) ; // operator T& used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>Both <code>const</code> and non-<code>const</code> objects can be wrapped. 
 | 
			
		||||
    Mutable objects can be modified directly from within the wrapper but constant
 | 
			
		||||
    objects cannot:</p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>value_initialized<int> x ; <br>static_cast<int&>(x) = 1 ; // OK<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> y ; <br>static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&<br>static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
 | 
			
		||||
                    
 | 
			
		||||
<h3>Warning:</h3>
 | 
			
		||||
                   
 | 
			
		||||
<p>Both the conversion operator and the <code>data()</code> member function 
 | 
			
		||||
    are <code>const</code> in order to allow access to the wrapped object 
 | 
			
		||||
from    a constant wrapper:</p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>void foo(int);<br>value_initialized<int> const x ;<br>foo(x);<br></pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>But notice that this conversion operator is to <code>T&</code> although 
 | 
			
		||||
    it is itself <code>const</code>. As a consequence, if <code>T</code> is
 | 
			
		||||
  a  non-<code>const</code> type, you can modify the wrapped object even from
 | 
			
		||||
   within a constant wrapper:</p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>value_initialized<int> const x_c ;<br>int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const.<br>xr = 2 ; </pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>The reason for this obscure behavior is that some commonly used compilers
 | 
			
		||||
     just don't accept the following valid code:</p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>struct X<br>{<br>  operator int&() ;<br>  operator int const&() const ;   <br>};<br>X x ;<br>(x == 1 ) ; // ERROR HERE!</pre>
 | 
			
		||||
                    
 | 
			
		||||
<p>These compilers complain about ambiguity between the conversion operators. 
 | 
			
		||||
    This complaint is incorrect, but the only workaround that I know of is 
 | 
			
		||||
 to   provide only one of them, which leads to the obscure behavior just explained.<br>
 | 
			
		||||
          </p>
 | 
			
		||||
                   
 | 
			
		||||
<h3>Recommended practice: The non-member get() idiom</h3>
 | 
			
		||||
                   
 | 
			
		||||
<p>The obscure behavior of being able to modify a non-<code>const</code>
 | 
			
		||||
wrapped object from within a constant wrapper can be avoided if access to
 | 
			
		||||
the wrapped object is always performed with the <code>get()</code> idiom:</p>
 | 
			
		||||
                   
 | 
			
		||||
<pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
 | 
			
		||||
 | 
			
		||||
<h2><a name="initialized_value"><code>class initialized_value</code></a></h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
class initialized_value
 | 
			
		||||
{
 | 
			
		||||
  public :
 | 
			
		||||
    template <class T> operator T() const ;
 | 
			
		||||
};
 | 
			
		||||
} // namespace boost
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
The class <code>initialized_value</code> provides a convenient way to get
 | 
			
		||||
an initialized value: its conversion operator provides an appropriate
 | 
			
		||||
<em>value-initialized</em> object for any CopyConstructible type.
 | 
			
		||||
 | 
			
		||||
Suppose you need to have an initialized variable of type <code>T</code>.
 | 
			
		||||
You could do it as follows:
 | 
			
		||||
<pre>
 | 
			
		||||
  T var = T();
 | 
			
		||||
</pre>
 | 
			
		||||
But as mentioned before, this form suffers from various compiler issues.
 | 
			
		||||
The template <code>value_initialized</code> offers a workaround:
 | 
			
		||||
<pre>
 | 
			
		||||
  T var = get( value_initialized<T>() );
 | 
			
		||||
</pre>
 | 
			
		||||
Unfortunately both forms repeat the type name, which
 | 
			
		||||
is rather short now (<code>T</code>), but could of course be 
 | 
			
		||||
more like <code>Namespace::Template<Arg>::Type</code>.
 | 
			
		||||
Instead, one could use <code>initialized_value</code> as follows:
 | 
			
		||||
<pre>
 | 
			
		||||
  T var = initialized_value();
 | 
			
		||||
</pre>
 | 
			
		||||
                    
 | 
			
		||||
<h3><a name="references">References</a></h3>
 | 
			
		||||
          [1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote
 | 
			
		||||
          various papers, proposing to extend the support for brace-enclosed <em>initializer lists</em>
 | 
			
		||||
          in the next version of C++.
 | 
			
		||||
          This would allow a variable <code>var</code> of any DefaultConstructible type
 | 
			
		||||
          <code>T</code> to be <em>value-initialized</em> by doing <code>T var = {}</code>.
 | 
			
		||||
          The papers are listed at Bjarne's web page,
 | 
			
		||||
          <a href="http://www.research.att.com/~bs/WG21.html">My C++ Standards committee papers</a>  <br> 
 | 
			
		||||
          [2] Scott Meyers, Effective C++, Third Edition, item 6,
 | 
			
		||||
          <em>Explicitly disallow the use of compiler-generated functions you do not want</em>, 
 | 
			
		||||
          <a href="http://www.aristeia.com/books.html">Scott Meyers: Books and CDs</a>  <br>
 | 
			
		||||
          [3] The C++ Standard, Second edition (2003), ISO/IEC 14882:2003 <br>
 | 
			
		||||
          [4] POD stands for "Plain Old Data"
 | 
			
		||||
 | 
			
		||||
<h3><a name="acknowledgements"></a>Acknowledgements</h3>
 | 
			
		||||
     value_initialized was developed by Fernando Cacciola, with help and
 | 
			
		||||
suggestions from David Abrahams and Darin Adler.<br>
 | 
			
		||||
Special thanks to Björn Karlsson who carefully edited and completed this documentation.
 | 
			
		||||
                 
 | 
			
		||||
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
 | 
			
		||||
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
 | 
			
		||||
     </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>.
 | 
			
		||||
     </p>
 | 
			
		||||
                    
 | 
			
		||||
<hr>          
 | 
			
		||||
<p>Revised 16 January 2008</p>
 | 
			
		||||
                   
 | 
			
		||||
<p>© Copyright Fernando Cacciola, 2002, 2008.</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>
 | 
			
		||||
 | 
			
		||||
 <br>
 | 
			
		||||
 <br>
 | 
			
		||||
    
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										330
									
								
								value_init_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										330
									
								
								value_init_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,330 @@
 | 
			
		||||
// 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)
 | 
			
		||||
//
 | 
			
		||||
// Test program for "boost/utility/value_init.hpp"
 | 
			
		||||
//
 | 
			
		||||
// 21 Ago 2002 (Created) Fernando Cacciola
 | 
			
		||||
// 18 Feb 2008 (Added tests regarding compiler issues and initialized_value) Fernando Cacciola, Niels Dekker
 | 
			
		||||
 | 
			
		||||
#include <cstring>  // For memcmp.
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "boost/utility/value_init.hpp"
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
#pragma hdrstop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "boost/test/minimal.hpp"
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Sample POD type
 | 
			
		||||
//
 | 
			
		||||
struct POD
 | 
			
		||||
{
 | 
			
		||||
  POD () : c(0), i(0), f(0) {}
 | 
			
		||||
 | 
			
		||||
  POD ( char c_, int i_, float f_ ) : c(c_), i(i_), f(f_) {}
 | 
			
		||||
 | 
			
		||||
  friend std::ostream& operator << ( std::ostream& os, POD const& pod )
 | 
			
		||||
    { return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; }
 | 
			
		||||
 | 
			
		||||
  friend bool operator == ( POD const& lhs, POD const& rhs )
 | 
			
		||||
    { return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
 | 
			
		||||
 | 
			
		||||
  float f;
 | 
			
		||||
  char  c;
 | 
			
		||||
  int   i;
 | 
			
		||||
} ;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Sample non POD type
 | 
			
		||||
//
 | 
			
		||||
struct NonPODBase
 | 
			
		||||
{
 | 
			
		||||
  virtual ~NonPODBase() {}
 | 
			
		||||
} ;
 | 
			
		||||
struct NonPOD : NonPODBase
 | 
			
		||||
{
 | 
			
		||||
  NonPOD () : id() {}
 | 
			
		||||
  explicit NonPOD ( std::string const& id_) : id(id_) {}
 | 
			
		||||
 | 
			
		||||
  friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod )
 | 
			
		||||
    { return os << '(' << npod.id << ')' ; }
 | 
			
		||||
 | 
			
		||||
  friend bool operator == ( NonPOD const& lhs, NonPOD const& rhs )
 | 
			
		||||
    { return lhs.id == rhs.id ; }
 | 
			
		||||
 | 
			
		||||
  std::string id ;
 | 
			
		||||
} ;
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Sample aggregate POD struct type
 | 
			
		||||
// Some compilers do not correctly value-initialize such a struct, for example:
 | 
			
		||||
// Borland C++ Report #51854, "Value-initialization: POD struct should be zero-initialized "
 | 
			
		||||
// http://qc.codegear.com/wc/qcmain.aspx?d=51854
 | 
			
		||||
//
 | 
			
		||||
struct AggregatePODStruct
 | 
			
		||||
{
 | 
			
		||||
  float f;
 | 
			
		||||
  char  c;
 | 
			
		||||
  int   i;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool operator == ( AggregatePODStruct const& lhs, AggregatePODStruct const& rhs )
 | 
			
		||||
{ return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// An aggregate struct that contains an std::string and an int.
 | 
			
		||||
// Pavel Kuznetsov (MetaCommunications Engineering) used a struct like
 | 
			
		||||
// this to reproduce the Microsoft Visual C++ compiler bug, reported as
 | 
			
		||||
// Feedback ID 100744, "Value-initialization in new-expression"
 | 
			
		||||
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
 | 
			
		||||
//
 | 
			
		||||
struct StringAndInt
 | 
			
		||||
{
 | 
			
		||||
  std::string s;
 | 
			
		||||
  int i;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool operator == ( StringAndInt const& lhs, StringAndInt const& rhs )
 | 
			
		||||
{ return lhs.s == rhs.s && lhs.i == rhs.i ; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// A struct that has an explicit (user defined) destructor.
 | 
			
		||||
// Some compilers do not correctly value-initialize such a struct, for example:
 | 
			
		||||
// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression"
 | 
			
		||||
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
 | 
			
		||||
//
 | 
			
		||||
struct StructWithDestructor
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  ~StructWithDestructor() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool operator == ( StructWithDestructor const& lhs, StructWithDestructor const& rhs )
 | 
			
		||||
{ return lhs.i == rhs.i ; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// A struct that has a virtual function.
 | 
			
		||||
// Some compilers do not correctly value-initialize such a struct either, for example:
 | 
			
		||||
// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression"
 | 
			
		||||
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
 | 
			
		||||
//
 | 
			
		||||
struct StructWithVirtualFunction
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  virtual void VirtualFunction(); 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void StructWithVirtualFunction::VirtualFunction()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool operator == ( StructWithVirtualFunction const& lhs, StructWithVirtualFunction const& rhs )
 | 
			
		||||
{ return lhs.i == rhs.i ; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// A struct that is derived from an aggregate POD struct.
 | 
			
		||||
// Some compilers do not correctly value-initialize such a struct, for example:
 | 
			
		||||
// GCC Bugzilla Bug 30111,  "Value-initialization of POD base class doesn't initialize members",
 | 
			
		||||
// reported by Jonathan Wakely, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111
 | 
			
		||||
//
 | 
			
		||||
struct DerivedFromAggregatePODStruct : AggregatePODStruct
 | 
			
		||||
{
 | 
			
		||||
  DerivedFromAggregatePODStruct() : AggregatePODStruct() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// A struct that wraps an aggregate POD struct as data member.
 | 
			
		||||
//
 | 
			
		||||
struct AggregatePODStructWrapper
 | 
			
		||||
{
 | 
			
		||||
  AggregatePODStructWrapper() : dataMember() {}
 | 
			
		||||
  AggregatePODStruct dataMember;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool operator == ( AggregatePODStructWrapper const& lhs, AggregatePODStructWrapper const& rhs )
 | 
			
		||||
{ return lhs.dataMember == rhs.dataMember ; }
 | 
			
		||||
 | 
			
		||||
typedef unsigned char ArrayOfBytes[256];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// A struct that allows testing whether the appropriate copy functions are called.
 | 
			
		||||
//
 | 
			
		||||
struct CopyFunctionCallTester
 | 
			
		||||
{
 | 
			
		||||
  bool is_copy_constructed;
 | 
			
		||||
  bool is_assignment_called;
 | 
			
		||||
 | 
			
		||||
  CopyFunctionCallTester()
 | 
			
		||||
  : is_copy_constructed(false), is_assignment_called(false) {}
 | 
			
		||||
 | 
			
		||||
  CopyFunctionCallTester(const CopyFunctionCallTester & )
 | 
			
		||||
  : is_copy_constructed(true), is_assignment_called(false) {}
 | 
			
		||||
 | 
			
		||||
  CopyFunctionCallTester & operator=(const CopyFunctionCallTester & )
 | 
			
		||||
  {
 | 
			
		||||
    is_assignment_called = true ;
 | 
			
		||||
    return *this ;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
void check_initialized_value ( T const& y )
 | 
			
		||||
{
 | 
			
		||||
  T initializedValue = boost::initialized_value() ;
 | 
			
		||||
  BOOST_CHECK ( y == initializedValue ) ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef  __BORLANDC__
 | 
			
		||||
#if __BORLANDC__ == 0x582
 | 
			
		||||
void check_initialized_value( NonPOD const& )
 | 
			
		||||
{
 | 
			
		||||
  // The initialized_value check is skipped for Borland 5.82
 | 
			
		||||
  // and this type (NonPOD), because the following statement
 | 
			
		||||
  // won't compile on this particular compiler version:
 | 
			
		||||
  //   NonPOD initializedValue = boost::initialized_value() ;
 | 
			
		||||
  //
 | 
			
		||||
  // This is caused by a compiler bug, that is fixed with a newer version
 | 
			
		||||
  // of the Borland compiler.  The Release Notes for Delphi(R) 2007 for
 | 
			
		||||
  // Win32(R) and C++Builder(R) 2007 (http://dn.codegear.com/article/36575)
 | 
			
		||||
  // say about similar statements:
 | 
			
		||||
  //   both of these statements now compile but under 5.82 got the error:
 | 
			
		||||
  //   Error E2015: Ambiguity between 'V::V(const A &)' and 'V::V(const V &)'
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// This test function tests boost::value_initialized<T> for a specific type T.
 | 
			
		||||
// The first argument (y) is assumed have the value of a value-initialized object.
 | 
			
		||||
// Returns true on success.
 | 
			
		||||
//
 | 
			
		||||
template<class T>
 | 
			
		||||
bool test ( T const& y, T const& z )
 | 
			
		||||
{
 | 
			
		||||
  const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
 | 
			
		||||
 | 
			
		||||
  check_initialized_value(y);
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<T> x ;
 | 
			
		||||
  BOOST_CHECK ( y == x ) ;
 | 
			
		||||
  BOOST_CHECK ( y == boost::get(x) ) ;
 | 
			
		||||
 | 
			
		||||
  static_cast<T&>(x) = z ;
 | 
			
		||||
  boost::get(x) = z ;
 | 
			
		||||
  BOOST_CHECK ( x == z ) ;
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<T> const x_c ;
 | 
			
		||||
  BOOST_CHECK ( y == x_c ) ;
 | 
			
		||||
  BOOST_CHECK ( y == boost::get(x_c) ) ;
 | 
			
		||||
  T& x_c_ref = x_c ;
 | 
			
		||||
  x_c_ref = z ;
 | 
			
		||||
  BOOST_CHECK ( x_c == z ) ;
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<T> const copy1 = x;
 | 
			
		||||
  BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ;
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<T> copy2;
 | 
			
		||||
  copy2 = x;
 | 
			
		||||
  BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ;
 | 
			
		||||
  
 | 
			
		||||
  boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
 | 
			
		||||
  BOOST_CHECK ( y == *ptr ) ;
 | 
			
		||||
 | 
			
		||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
 | 
			
		||||
  boost::value_initialized<T const> cx ;
 | 
			
		||||
  BOOST_CHECK ( y == cx ) ;
 | 
			
		||||
  BOOST_CHECK ( y == boost::get(cx) ) ;
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<T const> const cx_c ;
 | 
			
		||||
  BOOST_CHECK ( y == cx_c ) ;
 | 
			
		||||
  BOOST_CHECK ( y == boost::get(cx_c) ) ;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return boost::minimal_test::errors_counter() == counter_before_test ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int test_main(int, char **)
 | 
			
		||||
{
 | 
			
		||||
  BOOST_CHECK ( test( 0,1234 ) ) ;
 | 
			
		||||
  BOOST_CHECK ( test( 0.0,12.34 ) ) ;
 | 
			
		||||
  BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78) ) ) ;
 | 
			
		||||
  BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
 | 
			
		||||
 | 
			
		||||
  NonPOD NonPOD_object( std::string("NonPOD_object") );
 | 
			
		||||
  BOOST_CHECK ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
 | 
			
		||||
 | 
			
		||||
  AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
 | 
			
		||||
  AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
 | 
			
		||||
  BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
 | 
			
		||||
 | 
			
		||||
  StringAndInt stringAndInt0;
 | 
			
		||||
  StringAndInt stringAndInt1;
 | 
			
		||||
  stringAndInt0.i = 0;
 | 
			
		||||
  stringAndInt1.i = 1;
 | 
			
		||||
  stringAndInt1.s = std::string("1");
 | 
			
		||||
  BOOST_CHECK ( test(stringAndInt0, stringAndInt1) );
 | 
			
		||||
 | 
			
		||||
  StructWithDestructor structWithDestructor0;
 | 
			
		||||
  StructWithDestructor structWithDestructor1;
 | 
			
		||||
  structWithDestructor0.i = 0;
 | 
			
		||||
  structWithDestructor1.i = 1;
 | 
			
		||||
  BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) );
 | 
			
		||||
 | 
			
		||||
  StructWithVirtualFunction structWithVirtualFunction0;
 | 
			
		||||
  StructWithVirtualFunction structWithVirtualFunction1;
 | 
			
		||||
  structWithVirtualFunction0.i = 0;
 | 
			
		||||
  structWithVirtualFunction1.i = 1;
 | 
			
		||||
  BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
 | 
			
		||||
 | 
			
		||||
  DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
 | 
			
		||||
  DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
 | 
			
		||||
  static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
 | 
			
		||||
  static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
 | 
			
		||||
  BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
 | 
			
		||||
 | 
			
		||||
  AggregatePODStructWrapper aggregatePODStructWrapper0;
 | 
			
		||||
  AggregatePODStructWrapper aggregatePODStructWrapper1;
 | 
			
		||||
  aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
 | 
			
		||||
  aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
 | 
			
		||||
  BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
 | 
			
		||||
 | 
			
		||||
  ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
 | 
			
		||||
  boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
 | 
			
		||||
  BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
 | 
			
		||||
  valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
 | 
			
		||||
  BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
 | 
			
		||||
  BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
 | 
			
		||||
  BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
 | 
			
		||||
  BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed);
 | 
			
		||||
  BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called);
 | 
			
		||||
 | 
			
		||||
  boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
 | 
			
		||||
  copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
 | 
			
		||||
  BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed);
 | 
			
		||||
  BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unsigned int expected_failures = 0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								value_init_test_fail1.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								value_init_test_fail1.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
// Copyright 2002, 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)
 | 
			
		||||
//
 | 
			
		||||
// Test program for "boost/utility/value_init.hpp"
 | 
			
		||||
//
 | 
			
		||||
// Initial: 21 Agu 2002
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "boost/utility/value_init.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
#pragma hdrstop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "boost/test/minimal.hpp"
 | 
			
		||||
 | 
			
		||||
int test_main(int, char **)
 | 
			
		||||
{
 | 
			
		||||
  boost::value_initialized<int> const x_c ;
 | 
			
		||||
 | 
			
		||||
  get(x_c) = 1234 ; // this should produce an ERROR
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unsigned int expected_failures = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										36
									
								
								value_init_test_fail2.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								value_init_test_fail2.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
// Copyright 2002, 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)
 | 
			
		||||
//
 | 
			
		||||
// Test program for "boost/utility/value_init.hpp"
 | 
			
		||||
//
 | 
			
		||||
// Initial: 21 Agu 2002
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "boost/utility/value_init.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
#pragma hdrstop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "boost/test/minimal.hpp"
 | 
			
		||||
 | 
			
		||||
int test_main(int, char **)
 | 
			
		||||
{
 | 
			
		||||
  boost::value_initialized<int const> cx ;
 | 
			
		||||
 | 
			
		||||
  get(cx) = 1234 ; // this should produce an ERROR
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int expected_failures = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								value_init_test_fail3.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								value_init_test_fail3.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
// Copyright 2002, 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)
 | 
			
		||||
//
 | 
			
		||||
// Test program for "boost/utility/value_init.hpp"
 | 
			
		||||
//
 | 
			
		||||
// Initial: 21 Agu 2002
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "boost/utility/value_init.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef __BORLANDC__
 | 
			
		||||
#pragma hdrstop
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "boost/test/minimal.hpp"
 | 
			
		||||
 | 
			
		||||
int test_main(int, char **)
 | 
			
		||||
{
 | 
			
		||||
  boost::value_initialized<int const> const cx_c ;
 | 
			
		||||
 | 
			
		||||
  get(cx_c) = 1234 ; // this should produce an ERROR
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unsigned int expected_failures = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										126
									
								
								verify_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								verify_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,126 @@
 | 
			
		||||
//
 | 
			
		||||
//  verify_test.cpp - a test for BOOST_VERIFY
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 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)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
 | 
			
		||||
int f( int & x )
 | 
			
		||||
{
 | 
			
		||||
    return ++x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_default()
 | 
			
		||||
{
 | 
			
		||||
    int x = 1;
 | 
			
		||||
 | 
			
		||||
    BOOST_VERIFY( 1 );
 | 
			
		||||
    BOOST_VERIFY( x == 1 );
 | 
			
		||||
    BOOST_VERIFY( ++x );
 | 
			
		||||
    BOOST_VERIFY( f(x) );
 | 
			
		||||
    BOOST_VERIFY( &x );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( x == 3 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define BOOST_DISABLE_ASSERTS
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
 | 
			
		||||
void test_disabled()
 | 
			
		||||
{
 | 
			
		||||
    int x = 1;
 | 
			
		||||
 | 
			
		||||
    BOOST_VERIFY( 1 );
 | 
			
		||||
    BOOST_VERIFY( x == 1 );
 | 
			
		||||
    BOOST_VERIFY( ++x );
 | 
			
		||||
    BOOST_VERIFY( f(x) );
 | 
			
		||||
    BOOST_VERIFY( &x );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( x == 3 );
 | 
			
		||||
 | 
			
		||||
    BOOST_VERIFY( 0 );
 | 
			
		||||
    BOOST_VERIFY( !x );
 | 
			
		||||
    BOOST_VERIFY( x == 0 );
 | 
			
		||||
    BOOST_VERIFY( !++x );
 | 
			
		||||
    BOOST_VERIFY( !f(x) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( x == 5 );
 | 
			
		||||
 | 
			
		||||
    void * p = 0;
 | 
			
		||||
    BOOST_VERIFY( 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 bool f()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_VERIFY( 0 );
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void test_handler()
 | 
			
		||||
{
 | 
			
		||||
    int x = 1;
 | 
			
		||||
 | 
			
		||||
    BOOST_VERIFY( 1 );
 | 
			
		||||
    BOOST_VERIFY( x == 1 );
 | 
			
		||||
    BOOST_VERIFY( ++x );
 | 
			
		||||
    BOOST_VERIFY( f(x) );
 | 
			
		||||
    BOOST_VERIFY( &x );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( x == 3 );
 | 
			
		||||
 | 
			
		||||
    BOOST_VERIFY( 0 );
 | 
			
		||||
    BOOST_VERIFY( !x );
 | 
			
		||||
    BOOST_VERIFY( x == 0 );
 | 
			
		||||
    BOOST_VERIFY( !++x );
 | 
			
		||||
    BOOST_VERIFY( !f(x) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( x == 5 );
 | 
			
		||||
 | 
			
		||||
    void * p = 0;
 | 
			
		||||
    BOOST_VERIFY( p );
 | 
			
		||||
 | 
			
		||||
    BOOST_VERIFY( X::f() );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( handler_invoked == 8 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef BOOST_ENABLE_ASSERT_HANDLER
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    test_default();
 | 
			
		||||
    test_disabled();
 | 
			
		||||
    test_handler();
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user