forked from boostorg/utility
		
	Compare commits
	
		
			301 Commits
		
	
	
		
			svn-branch
			...
			boost-1.33
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9997fbb159 | ||
| 
						 | 
					2a50eba072 | ||
| 
						 | 
					1770e47f97 | ||
| 
						 | 
					d4f4893ee1 | ||
| 
						 | 
					23ec8fc788 | ||
| 
						 | 
					3ab8d14a59 | ||
| 
						 | 
					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 | 
@@ -15,7 +15,7 @@
 | 
			
		||||
</HEAD>
 | 
			
		||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b" 
 | 
			
		||||
        ALINK="#ff0000"> 
 | 
			
		||||
<IMG SRC="../../c++boost.gif" 
 | 
			
		||||
<IMG SRC="../../boost.png" 
 | 
			
		||||
     ALT="C++ Boost" width="277" height="86"> 
 | 
			
		||||
<!--end header-->
 | 
			
		||||
<BR Clear>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										648
									
								
								Collection.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										648
									
								
								Collection.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,648 @@
 | 
			
		||||
<HTML>
 | 
			
		||||
<!--
 | 
			
		||||
  -- Copyright (c) Jeremy Siek 2000
 | 
			
		||||
  --
 | 
			
		||||
  -- Permission to use, copy, modify, distribute and sell this software
 | 
			
		||||
  -- and its documentation for any purpose is hereby granted without fee,
 | 
			
		||||
  -- provided that the above copyright notice appears in all copies and
 | 
			
		||||
  -- that both that copyright notice and this permission notice appear
 | 
			
		||||
  -- in supporting documentation.  Silicon Graphics makes no
 | 
			
		||||
  -- representations about the suitability of this software for any
 | 
			
		||||
  -- purpose.  It is provided "as is" without express or implied warranty.
 | 
			
		||||
  -->
 | 
			
		||||
<Head>
 | 
			
		||||
<Title>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>
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
 | 
			
		||||
<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>The semantics of copying a Collection object is not defined (it
 | 
			
		||||
could be a deep or shallow copy or not even support copying). 
 | 
			
		||||
<LI>The associated reference type of a Collection does
 | 
			
		||||
not have to be a real C++ reference.
 | 
			
		||||
</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.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
<h3>Associated types</h3>
 | 
			
		||||
 | 
			
		||||
<Table border>
 | 
			
		||||
<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="#1">[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>
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
The following expressions must be valid.
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
<Table border>
 | 
			
		||||
<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>
 | 
			
		||||
<TR>
 | 
			
		||||
<TH>
 | 
			
		||||
Name
 | 
			
		||||
</TH>
 | 
			
		||||
<TH>
 | 
			
		||||
Expression
 | 
			
		||||
</TH>
 | 
			
		||||
<TH>
 | 
			
		||||
Semantics
 | 
			
		||||
</TH>
 | 
			
		||||
<TH>
 | 
			
		||||
Postcondition
 | 
			
		||||
</TH>
 | 
			
		||||
</TR>
 | 
			
		||||
<TD VAlign=top>
 | 
			
		||||
<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 
 | 
			
		||||
</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>
 | 
			
		||||
 | 
			
		||||
<tt>begin()</tt> and <tt>end()</tt> are amortized constant time.
 | 
			
		||||
<P>
 | 
			
		||||
<tt>size()</tt> is at most linear in the Collection's
 | 
			
		||||
size. <tt>empty()</tt> is amortized constant time.
 | 
			
		||||
<P>
 | 
			
		||||
<tt>swap()</tt> is at most linear in the size of the two collections.
 | 
			
		||||
<h3>Invariants</h3>
 | 
			
		||||
<Table border>
 | 
			
		||||
<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> <tt>array_ptr</tt>
 | 
			
		||||
<LI> <tt>vector<bool></tt>
 | 
			
		||||
</UL>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Collection Refinements</h3>
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
<h4>ForwardCollection</h4>
 | 
			
		||||
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>
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
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>
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
The elements are arranged in a strict linear order. No extra methods
 | 
			
		||||
are required.
 | 
			
		||||
 | 
			
		||||
<h4>RandomAccessCollection</h4>
 | 
			
		||||
 | 
			
		||||
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>
 | 
			
		||||
<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="1">[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).
 | 
			
		||||
 | 
			
		||||
<h3>See also</h3>
 | 
			
		||||
<A href="http://www.sgi.com/tech/stl/Container.html">Container</A>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<br>
 | 
			
		||||
<HR>
 | 
			
		||||
<TABLE>
 | 
			
		||||
<TR valign=top>
 | 
			
		||||
<TD nowrap>Copyright © 2000</TD><TD>
 | 
			
		||||
<A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>, Univ.of Notre Dame and C++ Library & Compiler Group/SGI (<A HREF="mailto:jsiek@engr.sgi.com">jsiek@engr.sgi.com</A>)
 | 
			
		||||
</TD></TR></TABLE>
 | 
			
		||||
 | 
			
		||||
</BODY>
 | 
			
		||||
</HTML> 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
</HEAD>
 | 
			
		||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b" 
 | 
			
		||||
        ALINK="#ff0000"> 
 | 
			
		||||
<IMG SRC="../../c++boost.gif" 
 | 
			
		||||
<IMG SRC="../../boost.png" 
 | 
			
		||||
     ALT="C++ Boost" width="277" height="86"> 
 | 
			
		||||
<!--end header-->
 | 
			
		||||
<BR Clear>
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@
 | 
			
		||||
</Head>
 | 
			
		||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b" 
 | 
			
		||||
        ALINK="#ff0000"> 
 | 
			
		||||
<IMG SRC="../../c++boost.gif" 
 | 
			
		||||
<IMG SRC="../../boost.png" 
 | 
			
		||||
     ALT="C++ Boost" width="277" height="86"> 
 | 
			
		||||
<!--end header-->
 | 
			
		||||
<BR Clear>
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
<Title>MultiPassInputIterator</Title>
 | 
			
		||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b" 
 | 
			
		||||
	ALINK="#ff0000"> 
 | 
			
		||||
<IMG SRC="../../c++boost.gif" 
 | 
			
		||||
<IMG SRC="../../boost.png" 
 | 
			
		||||
     ALT="C++ Boost" width="277" height="86"> 
 | 
			
		||||
 | 
			
		||||
<BR Clear>
 | 
			
		||||
@@ -30,9 +30,9 @@ 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.hmtl">Forward Iterator</a>. The
 | 
			
		||||
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.hmtl">Forward Iterator</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>
 | 
			
		||||
@@ -85,7 +85,7 @@ Once that is done we can drop Multi-Pass Input Iterator.
 | 
			
		||||
<TABLE>
 | 
			
		||||
<TR valign=top>
 | 
			
		||||
<TD nowrap>Copyright © 2000</TD><TD>
 | 
			
		||||
<A HREF=file:///c:/boost/site/people/jeremy_siek.htm>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
 | 
			
		||||
<a HREF="../../people/jeremy_siek.htm">Jeremy Siek</a>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
 | 
			
		||||
</TD></TR></TABLE>
 | 
			
		||||
 | 
			
		||||
</BODY>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										158
									
								
								OptionalPointee.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								OptionalPointee.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
<br>
 | 
			
		||||
<HR>
 | 
			
		||||
<TABLE>
 | 
			
		||||
<TR valign=top>
 | 
			
		||||
<TD nowrap>Copyright © 2003</TD><TD>
 | 
			
		||||
<A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A>,
 | 
			
		||||
based on the original concept developed by Augustus Saunders.
 | 
			
		||||
</TD></TR></TABLE>
 | 
			
		||||
 | 
			
		||||
</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();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								assert.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								assert.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
<!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">
 | 
			
		||||
					<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
 | 
			
		||||
				</td>
 | 
			
		||||
				<td align="middle">
 | 
			
		||||
					<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><br>
 | 
			
		||||
			<small>Copyright <20> 2002 by Peter Dimov. Permission to copy, use, modify, sell and 
 | 
			
		||||
				distribute this document is granted provided this copyright notice appears in 
 | 
			
		||||
				all copies. This document is provided "as is" without express or implied 
 | 
			
		||||
				warranty, and with no claim as to its suitability for any purpose.</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="../../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="../../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/">Preprocessor library</a>.
 | 
			
		||||
 | 
			
		||||
	<dt><a href="../../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;
 | 
			
		||||
}
 | 
			
		||||
@@ -5,14 +5,14 @@
 | 
			
		||||
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 4.0">
 | 
			
		||||
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
 | 
			
		||||
<title>Call Traits</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
 | 
			
		||||
vlink="#800080">
 | 
			
		||||
 | 
			
		||||
<h1><img src="../../c++boost.gif" width="276" height="86">Header
 | 
			
		||||
<h1><img src="../../boost.png" width="276" height="86">Header
 | 
			
		||||
<<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>></h1>
 | 
			
		||||
 | 
			
		||||
<p>All of the contents of <boost/call_traits.hpp> are
 | 
			
		||||
@@ -592,7 +592,8 @@ would prevent template argument deduction from functioning.</p>
 | 
			
		||||
<p>The call_traits template will "optimize" the passing
 | 
			
		||||
of a small built-in type as a function parameter, this mainly has
 | 
			
		||||
an effect when the parameter is used within a loop body. In the
 | 
			
		||||
following example (see <a href="algo_opt_examples.cpp">algo_opt_examples.cpp</a>),
 | 
			
		||||
following example (see <a
 | 
			
		||||
href="../type_traits/examples/fill_example.cpp">fill_example.cpp</a>),
 | 
			
		||||
a version of std::fill is optimized in two ways: if the type
 | 
			
		||||
passed is a single byte built-in type then std::memset is used to
 | 
			
		||||
effect the fill, otherwise a conventional C++ implemention is
 | 
			
		||||
@@ -748,10 +749,11 @@ no claim as to its suitability for any purpose.</p>
 | 
			
		||||
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
 | 
			
		||||
Hinnant and John Maddock.</p>
 | 
			
		||||
 | 
			
		||||
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
 | 
			
		||||
<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>
 | 
			
		||||
discussion list at <a
 | 
			
		||||
href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
 | 
			
		||||
 | 
			
		||||
<p>.</p>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,14 @@
 | 
			
		||||
 // boost::compressed_pair test program   
 | 
			
		||||
//  boost::compressed_pair test program   
 | 
			
		||||
    
 | 
			
		||||
 //  (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and   
 | 
			
		||||
 //  distribute this software is granted provided this copyright notice appears   
 | 
			
		||||
 //  in all copies. This software is provided "as is" without express or implied   
 | 
			
		||||
 //  warranty, and with no claim as to its suitability for any purpose.   
 | 
			
		||||
//  (C) Copyright John Maddock 2000. 
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// standalone test program for <boost/call_traits.hpp>
 | 
			
		||||
// 18 Mar 2002:
 | 
			
		||||
//    Changed some names to prevent conflicts with some new type_traits additions.
 | 
			
		||||
// 03 Oct 2000:
 | 
			
		||||
//    Enabled extra tests for VC6.
 | 
			
		||||
 | 
			
		||||
@@ -16,7 +19,46 @@
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/call_traits.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/type_traits/type_traits_test.hpp>
 | 
			
		||||
#include <libs/type_traits/test/test.hpp>
 | 
			
		||||
#include <libs/type_traits/test/check_type.hpp>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// define tests here
 | 
			
		||||
unsigned failures = 0;
 | 
			
		||||
unsigned test_count = 0;
 | 
			
		||||
//
 | 
			
		||||
// This must get defined within the test file.
 | 
			
		||||
// All compilers have bugs, set this to the number of
 | 
			
		||||
// regressions *expected* from a given compiler,
 | 
			
		||||
// if there are no workarounds for the bugs, *and*
 | 
			
		||||
// the regressions have been investigated.
 | 
			
		||||
//
 | 
			
		||||
extern unsigned int expected_failures;
 | 
			
		||||
//
 | 
			
		||||
// proc check_result()
 | 
			
		||||
// Checks that there were no regressions:
 | 
			
		||||
//
 | 
			
		||||
int check_result(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
   std::cout << test_count << " tests completed, "
 | 
			
		||||
      << failures << " failures found, "
 | 
			
		||||
      << expected_failures << " failures expected from this compiler." << std::endl;
 | 
			
		||||
   if((argc == 2) 
 | 
			
		||||
      && (argv[1][0] == '-')
 | 
			
		||||
      && (argv[1][1] == 'a')
 | 
			
		||||
      && (argv[1][2] == 0))
 | 
			
		||||
   {
 | 
			
		||||
      std::cout << "Press any key to continue...";
 | 
			
		||||
      std::cin.get();
 | 
			
		||||
   }
 | 
			
		||||
   return (failures == expected_failures)
 | 
			
		||||
       ? 0
 | 
			
		||||
       : (failures != 0) ? static_cast<int>(failures) : -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// a way prevent warnings for unused variables
 | 
			
		||||
template<class T> inline void unused_variable(const T&) {}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// struct contained models a type that contains a type (for example std::pair)
 | 
			
		||||
// arrays are contained by value, and have to be treated as a special case:
 | 
			
		||||
@@ -44,7 +86,7 @@ struct contained
 | 
			
		||||
   reference get() { return v_; }
 | 
			
		||||
   const_reference const_get()const { return v_; }
 | 
			
		||||
   // pass value:
 | 
			
		||||
   void call(param_type p){}
 | 
			
		||||
   void call(param_type){}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -69,12 +111,12 @@ struct contained<T[N]>
 | 
			
		||||
   // return by_ref:
 | 
			
		||||
   reference get() { return v_; }
 | 
			
		||||
   const_reference const_get()const { return v_; }
 | 
			
		||||
   void call(param_type p){}
 | 
			
		||||
   void call(param_type){}
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
contained<typename boost::call_traits<T>::value_type> wrap(const T& t)
 | 
			
		||||
contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t)
 | 
			
		||||
{
 | 
			
		||||
   typedef typename boost::call_traits<T>::value_type ct;
 | 
			
		||||
   return contained<ct>(t);
 | 
			
		||||
@@ -156,10 +198,10 @@ struct call_traits_checker<T[N]>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// check_wrap:
 | 
			
		||||
template <class T, class U>
 | 
			
		||||
void check_wrap(const contained<T>& w, const U& u)
 | 
			
		||||
template <class W, class U>
 | 
			
		||||
void check_wrap(const W& w, const U& u)
 | 
			
		||||
{
 | 
			
		||||
   cout << "checking contained<" << typeid(T).name() << ">..." << endl;
 | 
			
		||||
   cout << "checking " << typeid(W).name() << "..." << endl;
 | 
			
		||||
   assert(w.value() == u);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -181,6 +223,12 @@ struct comparible_UDT
 | 
			
		||||
{
 | 
			
		||||
   int i_;
 | 
			
		||||
   comparible_UDT() : i_(2){}
 | 
			
		||||
   comparible_UDT(const comparible_UDT& other) : i_(other.i_){}
 | 
			
		||||
   comparible_UDT& operator=(const comparible_UDT& other)
 | 
			
		||||
   { 
 | 
			
		||||
      i_ = other.i_;
 | 
			
		||||
      return *this;
 | 
			
		||||
   }
 | 
			
		||||
   bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -193,26 +241,23 @@ int main(int argc, char *argv[ ])
 | 
			
		||||
   int i = 2;
 | 
			
		||||
   c2(i);
 | 
			
		||||
   int* pi = &i;
 | 
			
		||||
#if (defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)) && !defined(__ICL)
 | 
			
		||||
   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__)
 | 
			
		||||
   int a[2] = {1,2};
 | 
			
		||||
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC)
 | 
			
		||||
   call_traits_checker<int[2]> c6;
 | 
			
		||||
   c6(a);
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   check_wrap(wrap(2), 2);
 | 
			
		||||
   const char ca[4] = "abc";
 | 
			
		||||
   // compiler can't deduce this for some reason:
 | 
			
		||||
   //check_wrap(wrap(ca), ca);
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
   check_wrap(wrap(a), a);
 | 
			
		||||
   check_wrap(test_wrap_type(2), 2);
 | 
			
		||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
 | 
			
		||||
   check_wrap(test_wrap_type(a), a);
 | 
			
		||||
   check_make_pair(test::make_pair(a, a), a, a);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -221,56 +266,66 @@ int main(int argc, char *argv[ ])
 | 
			
		||||
   typedef int& r_type;
 | 
			
		||||
   typedef const r_type cr_type;
 | 
			
		||||
 | 
			
		||||
   type_test(comparible_UDT, boost::call_traits<comparible_UDT>::value_type)
 | 
			
		||||
   type_test(comparible_UDT&, boost::call_traits<comparible_UDT>::reference)
 | 
			
		||||
   type_test(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference)
 | 
			
		||||
   type_test(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type)
 | 
			
		||||
   type_test(int, boost::call_traits<int>::value_type)
 | 
			
		||||
   type_test(int&, boost::call_traits<int>::reference)
 | 
			
		||||
   type_test(const int&, boost::call_traits<int>::const_reference)
 | 
			
		||||
   type_test(const int, boost::call_traits<int>::param_type)
 | 
			
		||||
   type_test(int*, boost::call_traits<int*>::value_type)
 | 
			
		||||
   type_test(int*&, boost::call_traits<int*>::reference)
 | 
			
		||||
   type_test(int*const&, boost::call_traits<int*>::const_reference)
 | 
			
		||||
   type_test(int*const, boost::call_traits<int*>::param_type)
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
 | 
			
		||||
   type_test(int&, boost::call_traits<int&>::value_type)
 | 
			
		||||
   type_test(int&, boost::call_traits<int&>::reference)
 | 
			
		||||
   type_test(const int&, boost::call_traits<int&>::const_reference)
 | 
			
		||||
   type_test(int&, boost::call_traits<int&>::param_type)
 | 
			
		||||
#if !(defined(__GNUC__) && (__GNUC__ < 4))
 | 
			
		||||
   type_test(int&, boost::call_traits<cr_type>::value_type)
 | 
			
		||||
   type_test(int&, boost::call_traits<cr_type>::reference)
 | 
			
		||||
   type_test(const int&, boost::call_traits<cr_type>::const_reference)
 | 
			
		||||
   type_test(int&, boost::call_traits<cr_type>::param_type)
 | 
			
		||||
   BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type);
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
   BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type);
 | 
			
		||||
#if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
 | 
			
		||||
   BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type);
 | 
			
		||||
#else
 | 
			
		||||
   std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl;
 | 
			
		||||
   failures += 4;
 | 
			
		||||
   test_count += 4;
 | 
			
		||||
#endif
 | 
			
		||||
   type_test(const int&, boost::call_traits<const int&>::value_type)
 | 
			
		||||
   type_test(const int&, boost::call_traits<const int&>::reference)
 | 
			
		||||
   type_test(const int&, boost::call_traits<const int&>::const_reference)
 | 
			
		||||
   type_test(const int&, boost::call_traits<const int&>::param_type)
 | 
			
		||||
   BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type);
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
   type_test(const int*, boost::call_traits<int[3]>::value_type)
 | 
			
		||||
   type_test(int(&)[3], boost::call_traits<int[3]>::reference)
 | 
			
		||||
   type_test(const int(&)[3], boost::call_traits<int[3]>::const_reference)
 | 
			
		||||
   type_test(const int*const, boost::call_traits<int[3]>::param_type)
 | 
			
		||||
   type_test(const int*, boost::call_traits<const int[3]>::value_type)
 | 
			
		||||
   type_test(const int(&)[3], boost::call_traits<const int[3]>::reference)
 | 
			
		||||
   type_test(const int(&)[3], boost::call_traits<const int[3]>::const_reference)
 | 
			
		||||
   type_test(const int*const, boost::call_traits<const int[3]>::param_type)
 | 
			
		||||
   BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type);
 | 
			
		||||
   // test with abstract base class:
 | 
			
		||||
   BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type);
 | 
			
		||||
#else
 | 
			
		||||
   std::cout << "You're compiler does not support partial template instantiation, skipping 8 tests (8 errors)" << std::endl;
 | 
			
		||||
   failures += 8;
 | 
			
		||||
   test_count += 8;
 | 
			
		||||
   std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl;
 | 
			
		||||
   failures += 12;
 | 
			
		||||
   test_count += 12;
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
   std::cout << "You're compiler does not support partial template instantiation, skipping 20 tests (20 errors)" << std::endl;
 | 
			
		||||
   failures += 20;
 | 
			
		||||
   test_count += 20;
 | 
			
		||||
   std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl;
 | 
			
		||||
   failures += 24;
 | 
			
		||||
   test_count += 24;
 | 
			
		||||
#endif
 | 
			
		||||
   // test with an incomplete type:
 | 
			
		||||
   BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type);
 | 
			
		||||
   BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference);
 | 
			
		||||
   BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
 | 
			
		||||
 | 
			
		||||
   return check_result(argc, argv);
 | 
			
		||||
}
 | 
			
		||||
@@ -312,6 +367,19 @@ void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T,
 | 
			
		||||
   param_type p2(v);
 | 
			
		||||
   param_type p3(r);
 | 
			
		||||
   param_type p4(p);
 | 
			
		||||
   
 | 
			
		||||
   unused_variable(v2);
 | 
			
		||||
   unused_variable(v3);
 | 
			
		||||
   unused_variable(v4);
 | 
			
		||||
   unused_variable(r2);
 | 
			
		||||
   unused_variable(r3);
 | 
			
		||||
   unused_variable(cr2);
 | 
			
		||||
   unused_variable(cr3);
 | 
			
		||||
   unused_variable(cr4);
 | 
			
		||||
   unused_variable(cr5);
 | 
			
		||||
   unused_variable(p2);
 | 
			
		||||
   unused_variable(p3);
 | 
			
		||||
   unused_variable(p4);
 | 
			
		||||
}
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
template <typename T>
 | 
			
		||||
@@ -348,6 +416,19 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>:
 | 
			
		||||
   param_type p2(v);
 | 
			
		||||
   param_type p3(r);
 | 
			
		||||
   param_type p4(p);
 | 
			
		||||
   
 | 
			
		||||
   unused_variable(v2);
 | 
			
		||||
   unused_variable(v3);
 | 
			
		||||
   unused_variable(v4);
 | 
			
		||||
   unused_variable(v5);
 | 
			
		||||
#ifndef __BORLANDC__
 | 
			
		||||
   unused_variable(r2);
 | 
			
		||||
   unused_variable(cr2);
 | 
			
		||||
#endif
 | 
			
		||||
   unused_variable(cr3);
 | 
			
		||||
   unused_variable(p2);
 | 
			
		||||
   unused_variable(p3);
 | 
			
		||||
   unused_variable(p4);
 | 
			
		||||
}
 | 
			
		||||
#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
//
 | 
			
		||||
@@ -355,26 +436,31 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>:
 | 
			
		||||
template struct call_traits_test<int>;
 | 
			
		||||
template struct call_traits_test<const int>;
 | 
			
		||||
template struct call_traits_test<int*>;
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
template struct call_traits_test<int&>;
 | 
			
		||||
template struct call_traits_test<const int&>;
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
 | 
			
		||||
template struct call_traits_test<int[2], true>;
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
unsigned int expected_failures = 10;
 | 
			
		||||
#if defined(BOOST_MSVC) && _MSC_VER <= 1300
 | 
			
		||||
unsigned int expected_failures = 12;
 | 
			
		||||
#elif defined(__SUNPRO_CC)
 | 
			
		||||
unsigned int expected_failures = 11;
 | 
			
		||||
#if(__SUNPRO_CC <= 0x520)
 | 
			
		||||
unsigned int expected_failures = 18;
 | 
			
		||||
#elif(__SUNPRO_CC < 0x530)
 | 
			
		||||
unsigned int expected_failures = 17;
 | 
			
		||||
#else
 | 
			
		||||
unsigned int expected_failures = 6;
 | 
			
		||||
#endif
 | 
			
		||||
#elif defined(__BORLANDC__)
 | 
			
		||||
unsigned int expected_failures = 2;
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
#elif (defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
 | 
			
		||||
unsigned int expected_failures = 4;
 | 
			
		||||
#elif defined(__HP_aCC)
 | 
			
		||||
unsigned int expected_failures = 24;
 | 
			
		||||
#else
 | 
			
		||||
unsigned int expected_failures = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										124
									
								
								checked_delete.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								checked_delete.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
			
		||||
<!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">
 | 
			
		||||
					<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
 | 
			
		||||
				</td>
 | 
			
		||||
				<td align="middle">
 | 
			
		||||
					<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. Permission to copy, use, modify, sell and 
 | 
			
		||||
				distribute this document is granted provided this copyright notice appears in 
 | 
			
		||||
				all copies. This document is provided "as is" without express or implied 
 | 
			
		||||
				warranty, and with no claim as to its suitability for any purpose.</small></p>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,17 +1,15 @@
 | 
			
		||||
//  Boost checked_delete test program  ---------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Beman Dawes 2001. Permission to copy, use, modify, sell
 | 
			
		||||
//  and distribute this software is granted provided this copyright
 | 
			
		||||
//  notice appears in all copies. This software is provided "as is" without
 | 
			
		||||
//  express or implied warranty, and with no claim as to its suitability for
 | 
			
		||||
//  any purpose.
 | 
			
		||||
//  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 for most recent version including documentation.
 | 
			
		||||
//  See http://www.boost.org/libs/utility for documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  21 May 01  Initial version (Beman Dawes)
 | 
			
		||||
 | 
			
		||||
#include <boost/utility.hpp>  // for checked_delete
 | 
			
		||||
#include <boost/checked_delete.hpp>  // for checked_delete
 | 
			
		||||
 | 
			
		||||
//  This program demonstrates compiler errors when trying to delete an
 | 
			
		||||
//  incomplete type.
 | 
			
		||||
@@ -23,9 +21,8 @@ namespace
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    Incomplete * p;
 | 
			
		||||
    Incomplete * p = 0;
 | 
			
		||||
    boost::checked_delete(p);          // should cause compile time error
 | 
			
		||||
    Incomplete ** pa;
 | 
			
		||||
    boost::checked_array_delete(pa);   // should cause compile time error
 | 
			
		||||
    boost::checked_array_delete(p);    // should cause compile time error
 | 
			
		||||
    return 0;
 | 
			
		||||
}   // main
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,19 @@
 | 
			
		||||
<html>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type"
 | 
			
		||||
content="text/html; charset=iso-8859-1">
 | 
			
		||||
<meta name="Template"
 | 
			
		||||
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
 | 
			
		||||
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
 | 
			
		||||
<title>Header </title>
 | 
			
		||||
<boost/compressed_pair.hpp>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
 | 
			
		||||
vlink="#800080">
 | 
			
		||||
 | 
			
		||||
<h2><img src="../../c++boost.gif" width="276" height="86">Header
 | 
			
		||||
<<a href="../../boost/detail/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 member optimisation" is applied to compress the
 | 
			
		||||
size of the pair.</p>
 | 
			
		||||
 | 
			
		||||
<pre>template <class T1, class T2>
 | 
			
		||||
   <head>
 | 
			
		||||
      <title>Header </title>
 | 
			
		||||
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
			
		||||
      <meta name="Template" content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
 | 
			
		||||
      <meta name="GENERATOR" content="Microsoft FrontPage Express 2.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:
 | 
			
		||||
@@ -52,47 +41,35 @@ public:
 | 
			
		||||
 | 
			
		||||
	void swap(compressed_pair& y);
 | 
			
		||||
};</pre>
 | 
			
		||||
 | 
			
		||||
<p>The two members of the pair can be accessed using the member
 | 
			
		||||
functions first() and second(). Note that not all member
 | 
			
		||||
functions can be instantiated for all template parameter types.
 | 
			
		||||
In particular compressed_pair can be instantiated for reference
 | 
			
		||||
and array types, however in these cases the range of constructors
 | 
			
		||||
that can be used are limited. If types T1 and T2 are the same
 | 
			
		||||
type, then there is only one version of the single-argument
 | 
			
		||||
constructor, and this constructor initialises both values in the
 | 
			
		||||
pair to the passed value.</p>
 | 
			
		||||
 | 
			
		||||
<p>Note that 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>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<p>Revised 08 May 2001</p>
 | 
			
		||||
 | 
			
		||||
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
 | 
			
		||||
sell and distribute this document is granted provided this
 | 
			
		||||
copyright notice appears in all copies. This document is provided
 | 
			
		||||
"as is" without express or implied warranty, and with
 | 
			
		||||
no claim as to its suitability for any purpose.</p>
 | 
			
		||||
 | 
			
		||||
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
 | 
			
		||||
Hinnant and John Maddock.</p>
 | 
			
		||||
 | 
			
		||||
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
 | 
			
		||||
Maddock</a>, the latest version of this file can be found at <a
 | 
			
		||||
href="http://www.boost.org">www.boost.org</a>, and the boost
 | 
			
		||||
discussion list at <a
 | 
			
		||||
href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
 | 
			
		||||
 | 
			
		||||
<p> </p>
 | 
			
		||||
</body>
 | 
			
		||||
      <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>
 | 
			
		||||
      <hr>
 | 
			
		||||
      <p>Revised 08 May 2001</p>
 | 
			
		||||
      <p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify, sell and 
 | 
			
		||||
         distribute this document is granted provided this copyright notice appears in 
 | 
			
		||||
         all copies. This document is provided "as is" without express or implied 
 | 
			
		||||
         warranty, and with no claim as to its suitability for any purpose.</p>
 | 
			
		||||
      <p>Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and John 
 | 
			
		||||
         Maddock.</p>
 | 
			
		||||
      <p>Maintained by <a href="mailto:john@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>
 | 
			
		||||
      <p> </p>
 | 
			
		||||
   </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
 // boost::compressed_pair test program   
 | 
			
		||||
//  boost::compressed_pair test program   
 | 
			
		||||
    
 | 
			
		||||
 //  (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and   
 | 
			
		||||
 //  distribute this software is granted provided this copyright notice appears   
 | 
			
		||||
 //  in all copies. This software is provided "as is" without express or implied   
 | 
			
		||||
 //  warranty, and with no claim as to its suitability for any purpose.   
 | 
			
		||||
//  (C) Copyright John Maddock 2000. 
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
 | 
			
		||||
// standalone test program for <boost/compressed_pair.hpp>
 | 
			
		||||
// Revised 03 Oct 2000: 
 | 
			
		||||
@@ -14,29 +14,23 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#include <boost/compressed_pair.hpp>
 | 
			
		||||
#include <boost/type_traits/type_traits_test.hpp>
 | 
			
		||||
#define BOOST_INCLUDE_MAIN
 | 
			
		||||
#include <boost/test/test_tools.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace boost;
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 | 
			
		||||
template <> struct is_empty<empty_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_empty<empty_POD_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
template <> struct is_POD<empty_POD_UDT>
 | 
			
		||||
{ static const bool value = true; };
 | 
			
		||||
#else
 | 
			
		||||
template <> struct is_empty<empty_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_empty<empty_POD_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
template <> struct is_POD<empty_POD_UDT>
 | 
			
		||||
{ enum{ value = true }; };
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
struct empty_UDT
 | 
			
		||||
{
 | 
			
		||||
   ~empty_UDT(){};
 | 
			
		||||
   empty_UDT& operator=(const empty_UDT&){ return *this; }
 | 
			
		||||
   bool operator==(const empty_UDT&)const
 | 
			
		||||
   { return true; }
 | 
			
		||||
};
 | 
			
		||||
struct empty_POD_UDT
 | 
			
		||||
{
 | 
			
		||||
   empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
 | 
			
		||||
   bool operator==(const empty_POD_UDT&)const
 | 
			
		||||
   { return true; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct non_empty1
 | 
			
		||||
{ 
 | 
			
		||||
@@ -85,47 +79,47 @@ void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type
 | 
			
		||||
   // first param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp2(p1);
 | 
			
		||||
   cp2.second() = p2;
 | 
			
		||||
   BOOST_TEST(cp2.first() == p1);
 | 
			
		||||
   BOOST_TEST(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_TEST(cp3.second() == p2);
 | 
			
		||||
   BOOST_TEST(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_TEST(cp4.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp4.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp4.second() == p2);
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp5(p3, p4);
 | 
			
		||||
   BOOST_TEST(cp5.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp5.second() == p4);
 | 
			
		||||
   BOOST_CHECK(cp5.first() == p3);
 | 
			
		||||
   BOOST_CHECK(cp5.second() == p4);
 | 
			
		||||
   // check const members:
 | 
			
		||||
   const boost::compressed_pair<T1,T2>& cpr1 = cp4;
 | 
			
		||||
   BOOST_TEST(cpr1.first() == p1);
 | 
			
		||||
   BOOST_TEST(cpr1.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cpr1.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cpr1.second() == p2);
 | 
			
		||||
 | 
			
		||||
   // copy construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp6(cp4);
 | 
			
		||||
   BOOST_TEST(cp6.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp6.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp6.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp6.second() == p2);
 | 
			
		||||
   // assignment:
 | 
			
		||||
   cp1 = cp4;
 | 
			
		||||
   BOOST_TEST(cp1.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp1.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp1.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp1.second() == p2);
 | 
			
		||||
   cp1 = cp5;
 | 
			
		||||
   BOOST_TEST(cp1.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp1.second() == p4);
 | 
			
		||||
   BOOST_CHECK(cp1.first() == p3);
 | 
			
		||||
   BOOST_CHECK(cp1.second() == p4);
 | 
			
		||||
   // swap:
 | 
			
		||||
   cp4.swap(cp5);
 | 
			
		||||
   BOOST_TEST(cp4.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p4);
 | 
			
		||||
   BOOST_TEST(cp5.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp5.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp4.first() == p3);
 | 
			
		||||
   BOOST_CHECK(cp4.second() == p4);
 | 
			
		||||
   BOOST_CHECK(cp5.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp5.second() == p2);
 | 
			
		||||
   swap(cp4,cp5);
 | 
			
		||||
   BOOST_TEST(cp4.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p2);
 | 
			
		||||
   BOOST_TEST(cp5.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp5.second() == p4);
 | 
			
		||||
   BOOST_CHECK(cp4.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp4.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp5.first() == p3);
 | 
			
		||||
   BOOST_CHECK(cp5.second() == p4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
@@ -154,20 +148,20 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_
 | 
			
		||||
#endif
 | 
			
		||||
   // both param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp4(p1, p2);
 | 
			
		||||
   BOOST_TEST(cp4.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp4.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp4.second() == p2);
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp5(p3, p4);
 | 
			
		||||
   BOOST_TEST(cp5.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp5.second() == p4);
 | 
			
		||||
   BOOST_CHECK(cp5.first() == p3);
 | 
			
		||||
   BOOST_CHECK(cp5.second() == p4);
 | 
			
		||||
   // check const members:
 | 
			
		||||
   const boost::compressed_pair<T1,T2>& cpr1 = cp4;
 | 
			
		||||
   BOOST_TEST(cpr1.first() == p1);
 | 
			
		||||
   BOOST_TEST(cpr1.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cpr1.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cpr1.second() == p2);
 | 
			
		||||
 | 
			
		||||
   // copy construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp6(cp4);
 | 
			
		||||
   BOOST_TEST(cp6.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp6.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp6.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp6.second() == p2);
 | 
			
		||||
   // assignment:
 | 
			
		||||
   // VC6 bug:
 | 
			
		||||
   // When second() is an empty class, VC6 performs the
 | 
			
		||||
@@ -180,8 +174,8 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_
 | 
			
		||||
   // settings - some generate the problem others do not.
 | 
			
		||||
   cp4.first() = p3;
 | 
			
		||||
   cp4.second() = p4;
 | 
			
		||||
   BOOST_TEST(cp4.first() == p3);
 | 
			
		||||
   BOOST_TEST(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:
 | 
			
		||||
@@ -199,14 +193,14 @@ struct compressed_pair_reference1_tester
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
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_TEST(cp2.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp2.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp2.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp2.second() == p2);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
//
 | 
			
		||||
@@ -225,14 +219,14 @@ struct compressed_pair_reference2_tester
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
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_TEST(cp3.second() == p2);
 | 
			
		||||
   BOOST_TEST(cp3.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cp3.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cp3.first() == p1);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -252,21 +246,21 @@ struct compressed_pair_array1_tester
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
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_TEST(cp3.second() == p2);
 | 
			
		||||
   BOOST_TEST(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_TEST(cpr1.first()[0] == p1[0]);
 | 
			
		||||
   BOOST_TEST(cpr1.second() == p2);
 | 
			
		||||
   BOOST_CHECK(cpr1.first()[0] == p1[0]);
 | 
			
		||||
   BOOST_CHECK(cpr1.second() == p2);
 | 
			
		||||
 | 
			
		||||
   BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
 | 
			
		||||
   BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
@@ -282,21 +276,21 @@ struct compressed_pair_array2_tester
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
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_TEST(cp2.first() == p1);
 | 
			
		||||
   BOOST_TEST(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_TEST(cpr1.first() == p1);
 | 
			
		||||
   BOOST_TEST(cpr1.second()[0] == p2[0]);
 | 
			
		||||
   BOOST_CHECK(cpr1.first() == p1);
 | 
			
		||||
   BOOST_CHECK(cpr1.second()[0] == p2[0]);
 | 
			
		||||
 | 
			
		||||
   BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
 | 
			
		||||
   BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
@@ -312,24 +306,24 @@ struct compressed_pair_array_tester
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
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_TEST(cp1.first()[0] == p1[0]);
 | 
			
		||||
   BOOST_TEST(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_TEST(cpr1.first()[0] == p1[0]);
 | 
			
		||||
   BOOST_TEST(cpr1.second()[0] == p2[0]);
 | 
			
		||||
   BOOST_CHECK(cpr1.first()[0] == p1[0]);
 | 
			
		||||
   BOOST_CHECK(cpr1.second()[0] == p2[0]);
 | 
			
		||||
 | 
			
		||||
   BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
 | 
			
		||||
   BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
 | 
			
		||||
   BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
 | 
			
		||||
   BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int test_main(int argc, char *argv[ ])
 | 
			
		||||
int test_main(int, char *[])
 | 
			
		||||
{
 | 
			
		||||
   // declare some variables to pass to the tester:
 | 
			
		||||
   non_empty1 ne1(2);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,325 +0,0 @@
 | 
			
		||||
<html>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 | 
			
		||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
<meta name="ProgId" content="FrontPage.Editor.Document">
 | 
			
		||||
<title>Counting Iterator Adaptor Documentation</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
 | 
			
		||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
 | 
			
		||||
align="center" width="277" height="86">
 | 
			
		||||
 | 
			
		||||
<h1>Counting Iterator Adaptor</h1>
 | 
			
		||||
 | 
			
		||||
Defined in header
 | 
			
		||||
<a href="../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
How would you fill up a vector with the numbers zero
 | 
			
		||||
through one hundred using <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/copy.html"><tt>std::copy()</tt></a>? The
 | 
			
		||||
only iterator operation missing from builtin integer types is an
 | 
			
		||||
<tt>operator*()</tt> that returns the current
 | 
			
		||||
value of the integer.  The counting iterator adaptor adds this crucial piece of
 | 
			
		||||
functionality to whatever type it wraps. One can use the
 | 
			
		||||
counting iterator adaptor not only with integer types, but with any
 | 
			
		||||
type that is <tt>Incrementable</tt> (see type requirements <a href="#requirements">below</a>).  The
 | 
			
		||||
following <b>pseudo-code</b> shows the general idea of how the
 | 
			
		||||
counting iterator is implemented.
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
  // inside a hypothetical counting_iterator class...
 | 
			
		||||
  typedef Incrementable value_type;
 | 
			
		||||
  value_type counting_iterator::operator*() const {
 | 
			
		||||
    return this->base; // no dereference!
 | 
			
		||||
  }
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
All of the other operators of the counting iterator behave in the same
 | 
			
		||||
fashion as the <tt>Incrementable</tt> base type.
 | 
			
		||||
 | 
			
		||||
<h2>Synopsis</h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template <class Incrementable>
 | 
			
		||||
  struct <a href="#counting_iterator_traits">counting_iterator_traits</a>;
 | 
			
		||||
 | 
			
		||||
  template <class Incrementable>
 | 
			
		||||
  struct <a href="#counting_iterator_generator">counting_iterator_generator</a>;
 | 
			
		||||
 | 
			
		||||
  template <class Incrementable>
 | 
			
		||||
  typename counting_iterator_generator<Incrementable>::type
 | 
			
		||||
  <a href="#make_counting_iterator">make_counting_iterator</a>(Incrementable x);
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<h2><a name="counting_iterator_generator">The Counting Iterator Type
 | 
			
		||||
Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
The class template <tt>counting_iterator_generator<Incrementable></tt> is a <a href="../../more/generic_programming.html#type_generator">type generator</a> for counting iterators.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <class Incrementable>
 | 
			
		||||
class counting_iterator_generator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type;
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
In this example we use the counting iterator generator to create a
 | 
			
		||||
counting iterator, and count from zero to four.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <boost/counting_iterator.hpp>
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  // Example of using counting_iterator_generator
 | 
			
		||||
  std::cout << "counting from 0 to 4:" << std::endl;
 | 
			
		||||
  boost::counting_iterator_generator<int>::type first(0), last(4);
 | 
			
		||||
  std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // to be continued...
 | 
			
		||||
</pre>
 | 
			
		||||
The output from this part is:
 | 
			
		||||
<pre>
 | 
			
		||||
counting from 0 to 4:
 | 
			
		||||
0 1 2 3 
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
<Table border>
 | 
			
		||||
<TR>
 | 
			
		||||
<TH>Parameter</TH><TH>Description</TH>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>Incrementable</tt></TD>
 | 
			
		||||
<TD>The type being wrapped by the adaptor.</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
</Table>
 | 
			
		||||
 | 
			
		||||
<h3>Model of</h3>
 | 
			
		||||
 | 
			
		||||
If the <tt>Incrementable</tt> type has all of the functionality of a
 | 
			
		||||
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
Access Iterator</a> except the <tt>operator*()</tt>, then the counting
 | 
			
		||||
iterator will be a model of <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
Access Iterator</a>. If the <tt>Incrementable</tt> type has less
 | 
			
		||||
functionality, then the counting iterator will have correspondingly
 | 
			
		||||
less functionality.
 | 
			
		||||
 | 
			
		||||
<h3><a name="requirements">Type Requirements</a></h3>
 | 
			
		||||
 | 
			
		||||
The <tt>Incrementable</tt> type must be <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default
 | 
			
		||||
Constructible</a>, <a href="./CopyConstructible.html">Copy
 | 
			
		||||
Constructible</a>, and <a href="./Assignable.html">Assignable</a>.
 | 
			
		||||
Also, the <tt>Incrementable</tt> type must provide access to an
 | 
			
		||||
associated <tt>difference_type</tt> and <tt>iterator_category</tt>
 | 
			
		||||
through the <a
 | 
			
		||||
href="#counting_iterator_traits"><tt>counting_iterator_traits</tt></a>
 | 
			
		||||
class.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
Furthermore, if you wish to create a counting iterator that is a <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html"> Forward
 | 
			
		||||
Iterator</a>, then the following expressions must be valid:
 | 
			
		||||
<pre>
 | 
			
		||||
Incrementable i, j;
 | 
			
		||||
++i         // pre-increment
 | 
			
		||||
i == j      // operator equal
 | 
			
		||||
</pre>
 | 
			
		||||
If you wish to create a counting iterator that is a <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">
 | 
			
		||||
Bidirectional Iterator</a>, then pre-decrement is also required:
 | 
			
		||||
<pre>
 | 
			
		||||
--i
 | 
			
		||||
</pre>
 | 
			
		||||
If you wish to create a counting iterator that is a <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html"> Random
 | 
			
		||||
Access Iterator</a>, then these additional expressions are also required:
 | 
			
		||||
<pre>
 | 
			
		||||
<a href="#counting_iterator_traits">counting_iterator_traits</a><Incrementable>::difference_type n;
 | 
			
		||||
i += n
 | 
			
		||||
n = i - j
 | 
			
		||||
i < j
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Members</h3>
 | 
			
		||||
 | 
			
		||||
The counting iterator type implements the member functions and
 | 
			
		||||
operators required of the <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
Access Iterator</a> concept. In addition it has the following
 | 
			
		||||
constructor:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
counting_iterator_generator::type(const Incrementable& i)
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2><a name="make_counting_iterator">The Counting Iterator Object Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <class Incrementable>
 | 
			
		||||
typename counting_iterator_generator<Incrementable>::type
 | 
			
		||||
make_counting_iterator(Incrementable base);
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
An <a href="../../more/generic_programming.html#object_generator">object
 | 
			
		||||
generator</a> function that provides a convenient way to create counting
 | 
			
		||||
iterators.<p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
In this example we count from negative five to positive five, this
 | 
			
		||||
time using the <tt>make_counting_iterator()</tt> function to save some
 | 
			
		||||
typing.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
  // continuing from previous example...
 | 
			
		||||
 | 
			
		||||
  std::cout << "counting from -5 to 4:" << std::endl;
 | 
			
		||||
  std::copy(boost::make_counting_iterator(-5),
 | 
			
		||||
	    boost::make_counting_iterator(5),
 | 
			
		||||
	    std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // to be continued...
 | 
			
		||||
</pre>
 | 
			
		||||
The output from this part is:
 | 
			
		||||
<pre>
 | 
			
		||||
counting from -5 to 4:
 | 
			
		||||
-5 -4 -3 -2 -1 0 1 2 3 4 
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
In the next example we create an array of numbers, and then create a
 | 
			
		||||
second array of pointers, where each pointer is the address of a
 | 
			
		||||
number in the first array. The counting iterator makes it easy to do
 | 
			
		||||
this since dereferencing a counting iterator that is wrapping an
 | 
			
		||||
iterator over the array of numbers just returns a pointer to the
 | 
			
		||||
current location in the array. We then use the <a
 | 
			
		||||
href="./indirect_iterator.htm">indirect iterator adaptor</a> to print
 | 
			
		||||
out the number in the array by accessing the numbers through the array
 | 
			
		||||
of pointers.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
  // continuing from previous example...
 | 
			
		||||
 | 
			
		||||
  const int N = 7;
 | 
			
		||||
  std::vector<int> numbers;
 | 
			
		||||
  // Fill "numbers" array with [0,N)
 | 
			
		||||
  std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N),
 | 
			
		||||
	    std::back_inserter(numbers));
 | 
			
		||||
 | 
			
		||||
  std::vector<std::vector<int>::iterator> pointers;
 | 
			
		||||
 | 
			
		||||
  // Use counting iterator to fill in the array of pointers.
 | 
			
		||||
  std::copy(boost::make_counting_iterator(numbers.begin()),
 | 
			
		||||
	    boost::make_counting_iterator(numbers.end()),
 | 
			
		||||
	    std::back_inserter(pointers));
 | 
			
		||||
 | 
			
		||||
  // Use indirect iterator to print out numbers by accessing
 | 
			
		||||
  // them through the array of pointers.
 | 
			
		||||
  std::cout << "indirectly printing out the numbers from 0 to " 
 | 
			
		||||
	    << N << std::endl;
 | 
			
		||||
  std::copy(boost::make_indirect_iterator(pointers.begin()),
 | 
			
		||||
	    boost::make_indirect_iterator(pointers.end()),
 | 
			
		||||
	    std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
</pre>
 | 
			
		||||
The output is:
 | 
			
		||||
<pre>
 | 
			
		||||
indirectly printing out the numbers from 0 to 7
 | 
			
		||||
0 1 2 3 4 5 6 
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<h2><a name="counting_iterator_traits">Counting Iterator Traits</a></h2>
 | 
			
		||||
 | 
			
		||||
The counting iterator adaptor needs to determine the appropriate
 | 
			
		||||
<tt>difference_type</tt> and <tt>iterator_category</tt> to use based on the
 | 
			
		||||
<tt>Incrementable</tt> type supplied by the user.  The
 | 
			
		||||
<tt>counting_iterator_traits</tt> class provides these types.  If the
 | 
			
		||||
<tt>Incrementable</tt> type is an integral type or an iterator, these types
 | 
			
		||||
will be correctly deduced by the <tt>counting_iterator_traits</tt> provided by
 | 
			
		||||
the library. Otherwise, the user must specialize
 | 
			
		||||
<tt>counting_iterator_traits</tt> for her type or add nested typedefs to
 | 
			
		||||
her type to fulfill the needs of
 | 
			
		||||
<a href="http://www.sgi.com/tech/stl/iterator_traits.html">
 | 
			
		||||
<tt>std::iterator_traits</tt></a>.
 | 
			
		||||
 | 
			
		||||
<p>The following pseudocode describes how the <tt>counting_iterator_traits</tt> are determined:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <class Incrementable>
 | 
			
		||||
struct counting_iterator_traits
 | 
			
		||||
{
 | 
			
		||||
  if (numeric_limits<Incrementable>::is_specialized) {
 | 
			
		||||
    if (!numeric_limits<Incrementable>::is_integer)
 | 
			
		||||
       COMPILE_TIME_ERROR;
 | 
			
		||||
 | 
			
		||||
    if (!numeric_limits<Incrementable>::is_bounded
 | 
			
		||||
        && numeric_limits<Incrementable>::is_signed) {
 | 
			
		||||
        typedef Incrementable difference_type;
 | 
			
		||||
    }
 | 
			
		||||
    else if (numeric_limits<Incrementable>::is_integral) {
 | 
			
		||||
        typedef <i>next-larger-signed-type-or-intmax_t</i> difference_type;
 | 
			
		||||
    }
 | 
			
		||||
    typedef std::random_access_iterator_tag iterator_category;   
 | 
			
		||||
  } else {
 | 
			
		||||
    typedef std::iterator_traits<Incrementable>::difference_type difference_type;
 | 
			
		||||
    typedef std::iterator_traits<Incrementable>::iterator_category iterator_category;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>The italicized sections above are implementation details, but it is important
 | 
			
		||||
to know that the <tt>difference_type</tt> for integral types is selected so that
 | 
			
		||||
it can always represent the difference between two values if such a built-in
 | 
			
		||||
integer exists. On platforms with a working <tt>std::numeric_limits</tt>
 | 
			
		||||
implementation, the <tt>difference_type</tt> for any variable-length signed
 | 
			
		||||
integer type <tt>T</tt> is <tt>T</tt> itself.
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->08 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14892" --></p>
 | 
			
		||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
 | 
			
		||||
modify, sell and distribute this document is granted provided this copyright
 | 
			
		||||
notice appears in all copies. This document is provided "as is"
 | 
			
		||||
without express or implied warranty, and with no claim as to its suitability for
 | 
			
		||||
any purpose.</p>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
<!--  LocalWords:  html charset alt gif hpp incrementable const namespace htm
 | 
			
		||||
 -->
 | 
			
		||||
<!--  LocalWords:  struct  typename iostream int Siek CopyConstructible pre
 | 
			
		||||
 -->
 | 
			
		||||
 | 
			
		||||
@@ -1,53 +0,0 @@
 | 
			
		||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
 | 
			
		||||
// distribute this software is granted provided this copyright notice appears
 | 
			
		||||
// in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
// warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <boost/counting_iterator.hpp>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  // Example of using counting_iterator_generator
 | 
			
		||||
  std::cout << "counting from 0 to 4:" << std::endl;
 | 
			
		||||
  boost::counting_iterator_generator<int>::type first(0), last(4);
 | 
			
		||||
  std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Example of using make_counting_iterator()
 | 
			
		||||
  std::cout << "counting from -5 to 4:" << std::endl;
 | 
			
		||||
  std::copy(boost::make_counting_iterator(-5),
 | 
			
		||||
	    boost::make_counting_iterator(5),
 | 
			
		||||
	    std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Example of using counting iterator to create an array of pointers.
 | 
			
		||||
  const int N = 7;
 | 
			
		||||
  std::vector<int> numbers;
 | 
			
		||||
  // Fill "numbers" array with [0,N)
 | 
			
		||||
  std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N),
 | 
			
		||||
	    std::back_inserter(numbers));
 | 
			
		||||
 | 
			
		||||
  std::vector<std::vector<int>::iterator> pointers;
 | 
			
		||||
 | 
			
		||||
  // Use counting iterator to fill in the array of pointers.
 | 
			
		||||
  std::copy(boost::make_counting_iterator(numbers.begin()),
 | 
			
		||||
	    boost::make_counting_iterator(numbers.end()),
 | 
			
		||||
	    std::back_inserter(pointers));
 | 
			
		||||
 | 
			
		||||
  // Use indirect iterator to print out numbers by accessing
 | 
			
		||||
  // them through the array of pointers.
 | 
			
		||||
  std::cout << "indirectly printing out the numbers from 0 to " 
 | 
			
		||||
	    << N << std::endl;
 | 
			
		||||
  std::copy(boost::make_indirect_iterator(pointers.begin()),
 | 
			
		||||
	    boost::make_indirect_iterator(pointers.end()),
 | 
			
		||||
	    std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,263 +0,0 @@
 | 
			
		||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
 | 
			
		||||
// distribute this software is granted provided this copyright notice appears in
 | 
			
		||||
// all copies. This software is provided "as is" without express or implied
 | 
			
		||||
// warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
//
 | 
			
		||||
// Revision History
 | 
			
		||||
// 16 Feb 2001  Added a missing const. Made the tests run (somewhat) with
 | 
			
		||||
//              plain MSVC again. (David Abrahams)
 | 
			
		||||
// 11 Feb 2001  #if 0'd out use of counting_iterator on non-numeric types in
 | 
			
		||||
//              MSVC without STLport, so that the other tests may proceed
 | 
			
		||||
//              (David Abrahams)
 | 
			
		||||
// 04 Feb 2001  Added use of iterator_tests.hpp (David Abrahams)
 | 
			
		||||
// 28 Jan 2001  Removed not_an_iterator detritus (David Abrahams)
 | 
			
		||||
// 24 Jan 2001  Initial revision (David Abrahams)
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(disable:4786) // identifier truncated in debug info
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/pending/iterator_tests.hpp>
 | 
			
		||||
#include <boost/counting_iterator.hpp>
 | 
			
		||||
#include <boost/detail/iterator.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <climits>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <boost/utility.hpp>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#ifndef BOOST_NO_LIMITS
 | 
			
		||||
# include <limits>
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_NO_SLIST
 | 
			
		||||
# include <slist>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template <class T> struct is_numeric
 | 
			
		||||
{
 | 
			
		||||
    enum { value = 
 | 
			
		||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
 | 
			
		||||
        std::numeric_limits<T>::is_specialized
 | 
			
		||||
#else
 | 
			
		||||
        // Causes warnings with GCC, but how else can I detect numeric types at
 | 
			
		||||
        // compile-time?
 | 
			
		||||
        (boost::is_convertible<int,T>::value &&
 | 
			
		||||
         boost::is_convertible<T,int>::value)
 | 
			
		||||
#endif
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Special tests for RandomAccess CountingIterators.
 | 
			
		||||
template <class CountingIterator>
 | 
			
		||||
void category_test(
 | 
			
		||||
    CountingIterator start,
 | 
			
		||||
    CountingIterator finish,
 | 
			
		||||
    std::random_access_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename
 | 
			
		||||
        boost::detail::iterator_traits<CountingIterator>::difference_type
 | 
			
		||||
        difference_type;
 | 
			
		||||
    difference_type distance = boost::detail::distance(start, finish);
 | 
			
		||||
 | 
			
		||||
    // Pick a random position internal to the range
 | 
			
		||||
    difference_type offset = (unsigned)rand() % distance;
 | 
			
		||||
    assert(offset >= 0);
 | 
			
		||||
    CountingIterator internal = start;
 | 
			
		||||
    std::advance(internal, offset);
 | 
			
		||||
 | 
			
		||||
    // Try some binary searches on the range to show that it's ordered
 | 
			
		||||
    assert(std::binary_search(start, finish, *internal));
 | 
			
		||||
    CountingIterator x,y;
 | 
			
		||||
    boost::tie(x,y) = std::equal_range(start, finish, *internal);
 | 
			
		||||
    assert(boost::detail::distance(x, y) == 1);
 | 
			
		||||
 | 
			
		||||
    // Show that values outside the range can't be found
 | 
			
		||||
    assert(!std::binary_search(start, boost::prior(finish), *finish));
 | 
			
		||||
 | 
			
		||||
    // Do the generic random_access_iterator_test
 | 
			
		||||
    typedef typename CountingIterator::value_type value_type;
 | 
			
		||||
    std::vector<value_type> v;
 | 
			
		||||
    for (value_type z = *start; z != *finish; ++z)
 | 
			
		||||
        v.push_back(z);
 | 
			
		||||
    if (v.size() >= 2)
 | 
			
		||||
    {
 | 
			
		||||
        // Note that this test requires a that the first argument is
 | 
			
		||||
        // dereferenceable /and/ a valid iterator prior to the first argument
 | 
			
		||||
        boost::random_access_iterator_test(start + 1, v.size() - 1, v.begin() + 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Special tests for bidirectional CountingIterators
 | 
			
		||||
template <class CountingIterator>
 | 
			
		||||
void category_test(CountingIterator start, CountingIterator finish, std::bidirectional_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
    if (finish != start
 | 
			
		||||
        && finish != boost::next(start)
 | 
			
		||||
        && finish != boost::next(boost::next(start)))
 | 
			
		||||
    {
 | 
			
		||||
        // Note that this test requires a that the first argument is
 | 
			
		||||
        // dereferenceable /and/ a valid iterator prior to the first argument
 | 
			
		||||
        boost::bidirectional_iterator_test(boost::next(start), boost::next(*start), boost::next(boost::next(*start)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class CountingIterator>
 | 
			
		||||
void category_test(CountingIterator start, CountingIterator finish, std::forward_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
    if (finish != start && finish != boost::next(start))
 | 
			
		||||
        boost::forward_iterator_test(start, *start, boost::next(*start));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class CountingIterator>
 | 
			
		||||
void test_aux(CountingIterator start, CountingIterator finish)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename CountingIterator::iterator_category category;
 | 
			
		||||
    typedef typename CountingIterator::value_type value_type;
 | 
			
		||||
 | 
			
		||||
    // If it's a RandomAccessIterator we can do a few delicate tests
 | 
			
		||||
    category_test(start, finish, category());
 | 
			
		||||
    
 | 
			
		||||
    // Okay, brute force...
 | 
			
		||||
    for (CountingIterator p = start; p != finish && boost::next(p) != finish; ++p)
 | 
			
		||||
    {
 | 
			
		||||
        assert(boost::next(*p) == *boost::next(p));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // prove that a reference can be formed to these values
 | 
			
		||||
    typedef typename CountingIterator::value_type value;
 | 
			
		||||
    const value* q = &*start;
 | 
			
		||||
    (void)q; // suppress unused variable warning
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Incrementable>
 | 
			
		||||
void test(Incrementable start, Incrementable finish)
 | 
			
		||||
{
 | 
			
		||||
    test_aux(boost::make_counting_iterator(start), boost::make_counting_iterator(finish));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Integer>
 | 
			
		||||
void test_integer(Integer* = 0) // default arg works around MSVC bug
 | 
			
		||||
{
 | 
			
		||||
    Integer start = 0;
 | 
			
		||||
    Integer finish = 120;
 | 
			
		||||
    test(start, finish);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Container>
 | 
			
		||||
void test_container(Container* = 0)  // default arg works around MSVC bug
 | 
			
		||||
{
 | 
			
		||||
    Container c(1 + (unsigned)rand() % 1673);
 | 
			
		||||
 | 
			
		||||
    const typename Container::iterator start = c.begin();
 | 
			
		||||
    
 | 
			
		||||
    // back off by 1 to leave room for dereferenceable value at the end
 | 
			
		||||
    typename Container::iterator finish = start;
 | 
			
		||||
    std::advance(finish, c.size() - 1);
 | 
			
		||||
    
 | 
			
		||||
    test(start, finish);
 | 
			
		||||
 | 
			
		||||
    typedef typename Container::const_iterator const_iterator;
 | 
			
		||||
    test(const_iterator(start), const_iterator(finish));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class my_int1 {
 | 
			
		||||
public:
 | 
			
		||||
  my_int1() { }
 | 
			
		||||
  my_int1(int x) : m_int(x) { }
 | 
			
		||||
  my_int1& operator++() { ++m_int; return *this; }
 | 
			
		||||
  bool operator==(const my_int1& x) const { return m_int == x.m_int; }
 | 
			
		||||
private:
 | 
			
		||||
  int m_int;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template <>
 | 
			
		||||
  struct counting_iterator_traits<my_int1> {
 | 
			
		||||
    typedef std::ptrdiff_t difference_type;
 | 
			
		||||
    typedef std::forward_iterator_tag iterator_category;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class my_int2 {
 | 
			
		||||
public:
 | 
			
		||||
  typedef void value_type;
 | 
			
		||||
  typedef void pointer;
 | 
			
		||||
  typedef void reference;
 | 
			
		||||
  typedef std::ptrdiff_t difference_type;
 | 
			
		||||
  typedef std::bidirectional_iterator_tag iterator_category;
 | 
			
		||||
 | 
			
		||||
  my_int2() { }
 | 
			
		||||
  my_int2(int x) : m_int(x) { }
 | 
			
		||||
  my_int2& operator++() { ++m_int; return *this; }
 | 
			
		||||
  my_int2& operator--() { --m_int; return *this; }
 | 
			
		||||
  bool operator==(const my_int2& x) const { return m_int == x.m_int; }
 | 
			
		||||
private:
 | 
			
		||||
  int m_int;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class my_int3 {
 | 
			
		||||
public:
 | 
			
		||||
  typedef void value_type;
 | 
			
		||||
  typedef void pointer;
 | 
			
		||||
  typedef void reference;
 | 
			
		||||
  typedef std::ptrdiff_t difference_type;
 | 
			
		||||
  typedef std::random_access_iterator_tag iterator_category;
 | 
			
		||||
 | 
			
		||||
  my_int3() { }
 | 
			
		||||
  my_int3(int x) : m_int(x) { }
 | 
			
		||||
  my_int3& operator++() { ++m_int; return *this; }
 | 
			
		||||
  my_int3& operator+=(std::ptrdiff_t n) { m_int += n; return *this; }
 | 
			
		||||
  std::ptrdiff_t operator-(const my_int3& x) const { return m_int - x.m_int; }
 | 
			
		||||
  my_int3& operator--() { --m_int; return *this; }
 | 
			
		||||
  bool operator==(const my_int3& x) const { return m_int == x.m_int; }
 | 
			
		||||
  bool operator!=(const my_int3& x) const { return m_int != x.m_int; }
 | 
			
		||||
  bool operator<(const my_int3& x) const { return m_int < x.m_int; }
 | 
			
		||||
private:
 | 
			
		||||
  int m_int;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    // Test the built-in integer types.
 | 
			
		||||
    test_integer<char>();
 | 
			
		||||
    test_integer<unsigned char>();
 | 
			
		||||
    test_integer<signed char>();
 | 
			
		||||
    test_integer<wchar_t>();
 | 
			
		||||
    test_integer<short>();
 | 
			
		||||
    test_integer<unsigned short>();
 | 
			
		||||
    test_integer<int>();
 | 
			
		||||
    test_integer<unsigned int>();
 | 
			
		||||
    test_integer<long>();
 | 
			
		||||
    test_integer<unsigned long>();
 | 
			
		||||
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
 | 
			
		||||
    test_integer<long long>();
 | 
			
		||||
    test_integer<unsigned long long>();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   // wrapping an iterator or non-built-in integer type causes an INTERNAL
 | 
			
		||||
   // COMPILER ERROR in MSVC without STLport. I'm clueless as to why.
 | 
			
		||||
#if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT)
 | 
			
		||||
    // Test user-defined type.
 | 
			
		||||
    test_integer<my_int1>();
 | 
			
		||||
    test_integer<my_int2>();
 | 
			
		||||
    test_integer<my_int3>();
 | 
			
		||||
    
 | 
			
		||||
   // Some tests on container iterators, to prove we handle a few different categories
 | 
			
		||||
    test_container<std::vector<int> >();
 | 
			
		||||
    test_container<std::list<int> >();
 | 
			
		||||
# ifndef BOOST_NO_SLIST
 | 
			
		||||
    test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
 | 
			
		||||
# endif
 | 
			
		||||
    
 | 
			
		||||
    // Also prove that we can handle raw pointers.
 | 
			
		||||
    int array[2000];
 | 
			
		||||
    test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1));
 | 
			
		||||
#endif
 | 
			
		||||
    std::cout << "test successful " << std::endl;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								current_function.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								current_function.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
<!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">
 | 
			
		||||
					<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
 | 
			
		||||
				</td>
 | 
			
		||||
				<td align="middle">
 | 
			
		||||
					<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. Permission to copy, use, modify, sell and 
 | 
			
		||||
				distribute this document is granted provided this copyright notice appears in 
 | 
			
		||||
				all copies. This document is provided "as is" without express or implied 
 | 
			
		||||
				warranty, and with no claim as to its suitability for any purpose.</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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										388
									
								
								enable_if.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								enable_if.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,388 @@
 | 
			
		||||
<!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></hr>
 | 
			
		||||
 | 
			
		||||
<B>Contributed by:</B> <BR>
 | 
			
		||||
Jaakko Järvi, Jeremiah Willcock and Andrew Lumsdaine<BR>
 | 
			
		||||
<EM>{jajarvi|jewillco|lums}@osl.iu.edu</EM><BR>
 | 
			
		||||
Indiana University<BR>
 | 
			
		||||
Open Systems Lab
 | 
			
		||||
<!--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>
 | 
			
		||||
							
								
								
									
										33
									
								
								enable_if/test/Jamfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								enable_if/test/Jamfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
# 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/
 | 
			
		||||
 | 
			
		||||
subproject libs/utility/enable_if/test ;
 | 
			
		||||
 | 
			
		||||
# bring in rules for testing
 | 
			
		||||
import testing ;
 | 
			
		||||
 | 
			
		||||
# Make tests run by default.
 | 
			
		||||
DEPENDS all : test ;
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    local test_monitor = <lib>@boost/libs/test/build/boost_test_exec_monitor ;
 | 
			
		||||
 | 
			
		||||
    # look in BOOST_ROOT for sources first, just in this Jamfile
 | 
			
		||||
    local SEARCH_SOURCE = $(BOOST_ROOT) $(SEARCH_SOURCE) ;
 | 
			
		||||
 | 
			
		||||
    test-suite utility/enable_if
 | 
			
		||||
        :
 | 
			
		||||
        [ run libs/utility/enable_if/test/constructors.cpp $(test_monitor) ]
 | 
			
		||||
        [ run libs/utility/enable_if/test/dummy_arg_disambiguation.cpp $(test_monitor) ]
 | 
			
		||||
        [ run libs/utility/enable_if/test/lazy.cpp $(test_monitor) ]
 | 
			
		||||
        [ run libs/utility/enable_if/test/lazy_test.cpp $(test_monitor) ]
 | 
			
		||||
        [ run libs/utility/enable_if/test/member_templates.cpp $(test_monitor) ]
 | 
			
		||||
        [ run libs/utility/enable_if/test/namespace_disambiguation.cpp $(test_monitor) ]
 | 
			
		||||
        [ run libs/utility/enable_if/test/no_disambiguation.cpp $(test_monitor) ]
 | 
			
		||||
        [ run libs/utility/enable_if/test/partial_specializations.cpp $(test_monitor) ]
 | 
			
		||||
    ;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
#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 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
#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 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
#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 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
// 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 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
#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 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
#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 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
#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 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
#include <boost/test/minimal.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/utility/enable_if.hpp>
 | 
			
		||||
#include <boost/type_traits/is_arithmetic.hpp>
 | 
			
		||||
 | 
			
		||||
using boost::enable_if_c;
 | 
			
		||||
using boost::disable_if_c;
 | 
			
		||||
using boost::enable_if;
 | 
			
		||||
using boost::disable_if;
 | 
			
		||||
using boost::is_arithmetic;
 | 
			
		||||
 | 
			
		||||
template <class T, class Enable = void>
 | 
			
		||||
struct tester;
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
struct tester<T, typename enable_if_c<is_arithmetic<T>::value>::type> {
 | 
			
		||||
  BOOST_STATIC_CONSTANT(bool, value = true);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
struct tester<T, typename disable_if_c<is_arithmetic<T>::value>::type> {
 | 
			
		||||
  BOOST_STATIC_CONSTANT(bool, value = false);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class Enable = void>
 | 
			
		||||
struct tester2;
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
struct tester2<T, typename enable_if<is_arithmetic<T> >::type> {
 | 
			
		||||
  BOOST_STATIC_CONSTANT(bool, value = true);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
struct tester2<T, typename disable_if<is_arithmetic<T> >::type> {
 | 
			
		||||
  BOOST_STATIC_CONSTANT(bool, value = false);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int test_main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
  BOOST_CHECK(tester<int>::value);
 | 
			
		||||
  BOOST_CHECK(tester<double>::value);
 | 
			
		||||
 | 
			
		||||
  BOOST_CHECK(!tester<char*>::value);
 | 
			
		||||
  BOOST_CHECK(!tester<void*>::value);
 | 
			
		||||
 | 
			
		||||
  BOOST_CHECK(tester2<int>::value);
 | 
			
		||||
  BOOST_CHECK(tester2<double>::value);
 | 
			
		||||
 | 
			
		||||
  BOOST_CHECK(!tester2<char*>::value);
 | 
			
		||||
  BOOST_CHECK(!tester2<void*>::value);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,273 +0,0 @@
 | 
			
		||||
<html>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 | 
			
		||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
<meta name="ProgId" content="FrontPage.Editor.Document">
 | 
			
		||||
<title>Filter Iterator Adaptor Documentation</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
 | 
			
		||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
 | 
			
		||||
align="center" width="277" height="86">
 | 
			
		||||
 | 
			
		||||
<h1>Filter Iterator Adaptor</h1>
 | 
			
		||||
 | 
			
		||||
Defined in header
 | 
			
		||||
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The filter iterator adaptor creates a view of an iterator range in
 | 
			
		||||
which some elements of the range are skipped over. A <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/Predicate.html">Predicate</a>
 | 
			
		||||
function object controls which elements are skipped. When the
 | 
			
		||||
predicate is applied to an element, if it returns <tt>true</tt> then
 | 
			
		||||
the element is retained and if it returns <tt>false</tt> then the
 | 
			
		||||
element is skipped over.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2>Synopsis</h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template <class Predicate, class BaseIterator, ...>
 | 
			
		||||
  class filter_iterator_generator;
 | 
			
		||||
 | 
			
		||||
  template <class Predicate, class BaseIterator>
 | 
			
		||||
  typename filter_iterator_generator<Predicate, BaseIterator>::type
 | 
			
		||||
  make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate());
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<h2><a name="filter_iterator_generator">The Filter Iterator Type
 | 
			
		||||
Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
The class <tt>filter_iterator_generator</tt> is a helper class whose
 | 
			
		||||
purpose is to construct a filter iterator type.  The template
 | 
			
		||||
parameters for this class are the <tt>Predicate</tt> function object
 | 
			
		||||
type and the <tt>BaseIterator</tt> type that is being wrapped.  In
 | 
			
		||||
most cases the associated types for the wrapped iterator can be
 | 
			
		||||
deduced from <tt>std::iterator_traits</tt>, but in some situations the
 | 
			
		||||
user may want to override these types, so there are also template
 | 
			
		||||
parameters for each of the iterator's associated types.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <class Predicate, class BaseIterator,
 | 
			
		||||
          class Value, class Reference, class Pointer, class Category, class Distance>
 | 
			
		||||
class filter_iterator_generator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting filter iterator type 
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
The following example uses filter iterator to print out all the
 | 
			
		||||
positive integers in an array. 
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
struct is_positive_number {
 | 
			
		||||
  bool operator()(int x) { return 0 < x; }
 | 
			
		||||
};
 | 
			
		||||
int main() {
 | 
			
		||||
  int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
 | 
			
		||||
  const int N = sizeof(numbers)/sizeof(int);
 | 
			
		||||
 | 
			
		||||
  typedef boost::filter_iterator_generator<is_positive_number, int*, int>::type FilterIter;
 | 
			
		||||
  is_positive_number predicate;
 | 
			
		||||
  FilterIter::policies_type policies(predicate, numbers + N);
 | 
			
		||||
  FilterIter filter_iter_first(numbers, policies);
 | 
			
		||||
  FilterIter filter_iter_last(numbers + N, policies);
 | 
			
		||||
 | 
			
		||||
  std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
The output is:
 | 
			
		||||
<pre>
 | 
			
		||||
4 5 8
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
<Table border>
 | 
			
		||||
<TR>
 | 
			
		||||
<TH>Parameter</TH><TH>Description</TH>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><a href="http://www.sgi.com/tech/stl/Predicate.html"><tt>Predicate</tt></a></TD>
 | 
			
		||||
<TD>The function object that determines which elements are retained and which elements are skipped.
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>BaseIterator</tt></TD>
 | 
			
		||||
<TD>The iterator type being wrapped. This type must at least be a model
 | 
			
		||||
 of the <a href="http://www.sgi.com/tech/stl/InputIterator">InputIterator</a> concept.</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>Value</tt></TD>
 | 
			
		||||
<TD>The <tt>value_type</tt> of the resulting iterator,
 | 
			
		||||
unless const. If const, a conforming compiler strips constness for the
 | 
			
		||||
<tt>value_type</tt>. Typically the default for this parameter is the
 | 
			
		||||
appropriate type<a href="#1">[1]</a>.<br> <b>Default:</b>
 | 
			
		||||
<tt>std::iterator_traits<BaseIterator>::value_type</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>Reference</tt></TD>
 | 
			
		||||
<TD>The <tt>reference</tt> type of the resulting iterator, and in
 | 
			
		||||
particular, the result type of <tt>operator*()</tt>. Typically the default for
 | 
			
		||||
this parameter is the appropriate type.<br> <b>Default:</b> If
 | 
			
		||||
<tt>Value</tt> is supplied, <tt>Value&</tt> is used. Otherwise
 | 
			
		||||
<tt>std::iterator_traits<BaseIterator>::reference</tt> is
 | 
			
		||||
used.</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>Pointer</tt></TD>
 | 
			
		||||
<TD>The <tt>pointer</tt> type of the resulting iterator, and in
 | 
			
		||||
 particular, the result type of <tt>operator->()</tt>. 
 | 
			
		||||
 Typically the default for
 | 
			
		||||
this parameter is the appropriate type.<br>
 | 
			
		||||
<b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
 | 
			
		||||
otherwise <tt>std::iterator_traits<BaseIterator>::pointer</tt>.</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>Category</tt></TD>
 | 
			
		||||
<TD>The <tt>iterator_category</tt> type for the resulting iterator.
 | 
			
		||||
Typically the
 | 
			
		||||
default for this parameter is the appropriate type. If you override
 | 
			
		||||
this parameter, do not use <tt>bidirectional_iterator_tag</tt>
 | 
			
		||||
because filter iterators can not go in reverse.<br>
 | 
			
		||||
<b>Default:</b> <tt>std::iterator_traits<BaseIterator>::iterator_category</tt></TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>Distance</tt></TD>
 | 
			
		||||
<TD>The <tt>difference_type</tt> for the resulting iterator. Typically the default for
 | 
			
		||||
this parameter is the appropriate type.<br>
 | 
			
		||||
<b>Default:</b> <tt>std::iterator_traits<BaseIterator>::difference_type</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Model of</h3>
 | 
			
		||||
 | 
			
		||||
The filter iterator adaptor (the type
 | 
			
		||||
<tt>filter_iterator_generator<...>::type</tt>) may be a model of <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> or <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>
 | 
			
		||||
depending on the adapted iterator type.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Members</h3>
 | 
			
		||||
 | 
			
		||||
The filter iterator type implements all of the member functions and
 | 
			
		||||
operators required of the <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>
 | 
			
		||||
concept.  In addition it has the following constructor:
 | 
			
		||||
 | 
			
		||||
<pre>filter_iterator_generator::type(const BaseIterator& it, const Policies& p = Policies())</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The policies type has only one public function, which is its constructor:
 | 
			
		||||
 | 
			
		||||
<pre>filter_iterator_generator::policies_type(const Predicate& p, const BaseIterator& end)</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
<h2><a name="make_filter_iterator">The Make Filter Iterator Function</a></h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <class Predicate, class BaseIterator>
 | 
			
		||||
typename detail::filter_generator<Predicate, BaseIterator>::type
 | 
			
		||||
make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate())
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
This function provides a convenient way to create filter iterators.
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
In this example we print out all numbers in the array that are
 | 
			
		||||
greater than negative two.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
 | 
			
		||||
  const int N = sizeof(numbers)/sizeof(int);
 | 
			
		||||
 | 
			
		||||
  std::copy(boost::make_filter_iterator(numbers, numbers + N, 
 | 
			
		||||
					std::bind2nd(std::greater<int>(), -2)),
 | 
			
		||||
	    boost::make_filter_iterator(numbers + N, numbers + N, 
 | 
			
		||||
					std::bind2nd(std::greater<int>(), -2)),
 | 
			
		||||
	    std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
The output is:
 | 
			
		||||
<pre>
 | 
			
		||||
0 -1 4 5 8 
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
In the next example we print the positive numbers using the
 | 
			
		||||
<tt>make_filter_iterator()</tt> function.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
struct is_positive_number {
 | 
			
		||||
  bool operator()(int x) { return 0 < x; }
 | 
			
		||||
};
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
 | 
			
		||||
  const int N = sizeof(numbers)/sizeof(int);
 | 
			
		||||
 | 
			
		||||
  std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
 | 
			
		||||
	    boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
 | 
			
		||||
	    std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
The output is:
 | 
			
		||||
<pre>
 | 
			
		||||
4 5 8
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Notes</h3>
 | 
			
		||||
 | 
			
		||||
<a name="1">[1]</a> If the compiler does not support partial
 | 
			
		||||
specialization and the wrapped iterator type is a builtin pointer then
 | 
			
		||||
the <tt>Value</tt> type must be explicitly specified (don't use the
 | 
			
		||||
default).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->09 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14894" --></p>
 | 
			
		||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
 | 
			
		||||
modify, sell and distribute this document is granted provided this copyright
 | 
			
		||||
notice appears in all copies. This document is provided "as is"
 | 
			
		||||
without express or implied warranty, and with no claim as to its suitability for
 | 
			
		||||
any purpose.</p>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,53 +0,0 @@
 | 
			
		||||
// Example of using the filter iterator adaptor from
 | 
			
		||||
// boost/iterator_adaptors.hpp.
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
struct is_positive_number {
 | 
			
		||||
  bool operator()(int x) { return 0 < x; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
 | 
			
		||||
  const int N = sizeof(numbers)/sizeof(int);
 | 
			
		||||
 | 
			
		||||
  // Example using make_filter_iterator()
 | 
			
		||||
  std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
 | 
			
		||||
	    boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
 | 
			
		||||
	    std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Example using filter_iterator_generator
 | 
			
		||||
  typedef boost::filter_iterator_generator<is_positive_number, int*, int>::type
 | 
			
		||||
    FilterIter;
 | 
			
		||||
  is_positive_number predicate;
 | 
			
		||||
  FilterIter::policies_type policies(predicate, numbers + N);
 | 
			
		||||
  FilterIter filter_iter_first(numbers, policies);
 | 
			
		||||
  FilterIter filter_iter_last(numbers + N, policies);
 | 
			
		||||
 | 
			
		||||
  std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Another example using make_filter_iterator()
 | 
			
		||||
  std::copy(boost::make_filter_iterator(numbers, numbers + N, 
 | 
			
		||||
					std::bind2nd(std::greater<int>(), -2)),
 | 
			
		||||
	    boost::make_filter_iterator(numbers + N, numbers + N, 
 | 
			
		||||
					std::bind2nd(std::greater<int>(), -2)),
 | 
			
		||||
	    std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,41 +0,0 @@
 | 
			
		||||
// (C) Copyright Jeremy Siek 2001. Permission to copy, use, modify,
 | 
			
		||||
// sell and distribute this software is granted provided this
 | 
			
		||||
// copyright notice appears in all copies. This software is provided
 | 
			
		||||
// "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
// to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
// Revision History:
 | 
			
		||||
 | 
			
		||||
// 27 Feb 2001   Jeremy Siek
 | 
			
		||||
//      Initial checkin.
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <boost/function_output_iterator.hpp>
 | 
			
		||||
 | 
			
		||||
struct string_appender {
 | 
			
		||||
  string_appender(std::string& s) : m_str(s) { }
 | 
			
		||||
  void operator()(const std::string& x) const {
 | 
			
		||||
    m_str += x;
 | 
			
		||||
  }
 | 
			
		||||
  std::string& m_str;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  std::vector<std::string> x;
 | 
			
		||||
  x.push_back("hello");
 | 
			
		||||
  x.push_back(" ");
 | 
			
		||||
  x.push_back("world");
 | 
			
		||||
  x.push_back("!");
 | 
			
		||||
 | 
			
		||||
  std::string s = "";
 | 
			
		||||
  std::copy(x.begin(), x.end(), 
 | 
			
		||||
	    boost::make_function_output_iterator(string_appender(s)));
 | 
			
		||||
  
 | 
			
		||||
  std::cout << s << std::endl;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,169 +0,0 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
 | 
			
		||||
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <meta name="generator" content="HTML Tidy, see www.w3.org">
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 | 
			
		||||
    <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
    <meta name="ProgId" content="FrontPage.Editor.Document">
 | 
			
		||||
 | 
			
		||||
    <title>Function Output Iterator Adaptor Documentation</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
        
 | 
			
		||||
    <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
 | 
			
		||||
    "center" width="277" height="86"> 
 | 
			
		||||
 | 
			
		||||
    <h1>Function Output Iterator Adaptor</h1>
 | 
			
		||||
    Defined in header <a href=
 | 
			
		||||
    "../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a> 
 | 
			
		||||
 | 
			
		||||
    <p>The function output iterator adaptor makes it easier to create
 | 
			
		||||
    custom output iterators. The adaptor takes a <a
 | 
			
		||||
    href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
 | 
			
		||||
    Function</a> and creates a model of <a
 | 
			
		||||
    href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
 | 
			
		||||
    Iterator</a>. Each item assigned to the output iterator is passed
 | 
			
		||||
    as an argument to the unary function.  The motivation for this
 | 
			
		||||
    iterator is that creating a C++ Standard conforming output
 | 
			
		||||
    iterator is non-trivial, particularly because the proper
 | 
			
		||||
    implementation usually requires a proxy object. On the other hand,
 | 
			
		||||
    creating a function (or function object) is much simpler.
 | 
			
		||||
 | 
			
		||||
    <h2>Synopsis</h2>
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template <class UnaryFunction>
 | 
			
		||||
  class function_output_iterator;
 | 
			
		||||
 | 
			
		||||
  template <class UnaryFunction>
 | 
			
		||||
  function_output_iterator<UnaryFunction>
 | 
			
		||||
  make_function_output_iterator(const UnaryFunction& f = UnaryFunction())
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Example</h3>
 | 
			
		||||
    
 | 
			
		||||
    In this example we create an output iterator that appends
 | 
			
		||||
    each item onto the end of a string, using the <tt>string_appender</tt>
 | 
			
		||||
    function. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <boost/function_output_iterator.hpp>
 | 
			
		||||
 | 
			
		||||
struct string_appender {
 | 
			
		||||
  string_appender(std::string& s) : m_str(s) { }
 | 
			
		||||
  void operator()(const std::string& x) const {
 | 
			
		||||
    m_str += x;
 | 
			
		||||
  }
 | 
			
		||||
  std::string& m_str;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  std::vector<std::string> x;
 | 
			
		||||
  x.push_back("hello");
 | 
			
		||||
  x.push_back(" ");
 | 
			
		||||
  x.push_back("world");
 | 
			
		||||
  x.push_back("!");
 | 
			
		||||
 | 
			
		||||
  std::string s = "";
 | 
			
		||||
  std::copy(x.begin(), x.end(), 
 | 
			
		||||
            boost::make_function_output_iterator(string_appender(s)));
 | 
			
		||||
  
 | 
			
		||||
  std::cout << s << std::endl;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="function_output_iterator">The Function Output Iterator Class</a></h2>
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class UnaryFunction>
 | 
			
		||||
class function_output_iterator;
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    The <tt>function_output_iterator</tt> class creates an <a
 | 
			
		||||
    href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
 | 
			
		||||
    Iterator</a> out of a
 | 
			
		||||
    <a href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
 | 
			
		||||
    Function</a>. Each item assigned to the output iterator is passed
 | 
			
		||||
    as an argument to the unary function.
 | 
			
		||||
 | 
			
		||||
    <h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
    <table border>
 | 
			
		||||
      <tr>
 | 
			
		||||
        <th>Parameter
 | 
			
		||||
 | 
			
		||||
        <th>Description
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>UnaryFunction</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The function type being wrapped. The return type of the
 | 
			
		||||
        function is not used, so it can be <tt>void</tt>.  The
 | 
			
		||||
        function must be a model of <a
 | 
			
		||||
        href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
 | 
			
		||||
        Function</a>.</td>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3>Concept Model</h3>
 | 
			
		||||
    The function output iterator class is a model of <a
 | 
			
		||||
    href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
 | 
			
		||||
    Iterator</a>.
 | 
			
		||||
 | 
			
		||||
    <h2>Members</h3>
 | 
			
		||||
    The function output iterator implements the member functions
 | 
			
		||||
    and operators required of the <a
 | 
			
		||||
    href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
 | 
			
		||||
    Iterator</a> concept. In addition it has the following constructor:
 | 
			
		||||
<pre>
 | 
			
		||||
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction())
 | 
			
		||||
</pre>
 | 
			
		||||
   <br>    
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
    <hr>
 | 
			
		||||
    <h2><a name="make_function_output_iterator">The Function Output Iterator Object
 | 
			
		||||
    Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
    The <tt>make_function_output_iterator()</tt> function provides a
 | 
			
		||||
    more convenient way to create function output iterator objects. The
 | 
			
		||||
    function saves the user the trouble of explicitly writing out the
 | 
			
		||||
    iterator types. If the default argument is used, the function
 | 
			
		||||
    type must be provided as an explicit template argument.
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class UnaryFunction>
 | 
			
		||||
function_output_iterator<UnaryFunction>
 | 
			
		||||
make_function_output_iterator(const UnaryFunction& f = UnaryFunction())
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <p>© Copyright Jeremy Siek 2001. Permission to copy, use,
 | 
			
		||||
    modify, sell and distribute this document is granted provided this
 | 
			
		||||
    copyright notice appears in all copies. This document is provided
 | 
			
		||||
    "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
    to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										150
									
								
								generator_iterator.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								generator_iterator.htm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
 | 
			
		||||
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
<title>Generator Iterator Adaptor Documentation</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
        
 | 
			
		||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" width="277" height="86"> 
 | 
			
		||||
 | 
			
		||||
<h1>Generator Iterator Adaptor</h1>
 | 
			
		||||
Defined in header <a href="../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a> 
 | 
			
		||||
<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.
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
<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>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>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<h3>Concept Model</h3>
 | 
			
		||||
The generator iterator class is a model of
 | 
			
		||||
<a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.
 | 
			
		||||
 | 
			
		||||
<h3>Members</h3>
 | 
			
		||||
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>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<h2><a name="make_generator_iterator">The Generator Iterator Object Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
<blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class Generator>
 | 
			
		||||
typename generator_iterator_generator<Generator>::type
 | 
			
		||||
make_generator_iterator(Generator & gen);
 | 
			
		||||
</pre>
 | 
			
		||||
</blockquote>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
The following program shows how <code>generator_iterator</code>
 | 
			
		||||
transforms a generator into an input iterator.
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
Written by Jens Maurer.
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,366 +0,0 @@
 | 
			
		||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
 | 
			
		||||
// distribute this software is granted provided this copyright notice appears in
 | 
			
		||||
// all copies. This software is provided "as is" without express or implied
 | 
			
		||||
// warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
//
 | 
			
		||||
// Revision History
 | 
			
		||||
// 11 Feb 2001  Compile with Borland, re-enable failing tests (David Abrahams)
 | 
			
		||||
// 29 Jan 2001  Initial revision (David Abrahams)
 | 
			
		||||
 | 
			
		||||
#include <boost/half_open_range.hpp>
 | 
			
		||||
#include <boost/utility.hpp>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#ifndef BOOST_NO_LIMITS
 | 
			
		||||
# include <limits>
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_NO_SLIST
 | 
			
		||||
# include <slist>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline unsigned unsigned_random(unsigned max)
 | 
			
		||||
{
 | 
			
		||||
    return (max > 0) ? (unsigned)rand() % max : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Special tests for ranges supporting random access
 | 
			
		||||
template <class T>
 | 
			
		||||
void category_test_1(
 | 
			
		||||
    const boost::half_open_range<T>& r, std::random_access_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
    typedef boost::half_open_range<T> range;
 | 
			
		||||
    typedef typename range::size_type size_type;
 | 
			
		||||
    size_type size = r.size();
 | 
			
		||||
 | 
			
		||||
    // pick a random offset
 | 
			
		||||
    size_type offset = unsigned_random(size);
 | 
			
		||||
 | 
			
		||||
    typename range::value_type x = *(r.begin() + offset);
 | 
			
		||||
    // test contains(value_type)
 | 
			
		||||
    assert(r.contains(r.start()) == !r.empty());
 | 
			
		||||
    assert(!r.contains(r.finish()));
 | 
			
		||||
    assert(r.contains(x) == (offset != size));
 | 
			
		||||
 | 
			
		||||
    range::const_iterator p = r.find(x);
 | 
			
		||||
    assert((p == r.end()) == (x == r.finish()));
 | 
			
		||||
    assert(r.find(r.finish()) == r.end());
 | 
			
		||||
 | 
			
		||||
    if (offset != size)
 | 
			
		||||
    {
 | 
			
		||||
        assert(x == r[offset]);
 | 
			
		||||
        assert(x == r.at(offset));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool caught_out_of_range = false;
 | 
			
		||||
    try {
 | 
			
		||||
        bool never_initialized = x == r.at(size);
 | 
			
		||||
        (void)never_initialized;
 | 
			
		||||
    }
 | 
			
		||||
    catch(std::out_of_range&)
 | 
			
		||||
    {
 | 
			
		||||
        caught_out_of_range = true;
 | 
			
		||||
    }
 | 
			
		||||
    catch(...)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
    assert(caught_out_of_range);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Those tests must be skipped for other ranges
 | 
			
		||||
template <class T>
 | 
			
		||||
void category_test_1(
 | 
			
		||||
    const boost::half_open_range<T>&, std::forward_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned indices[][2] = { {0,0},{0,1},{0,2},{0,3},
 | 
			
		||||
                                {1,1},{1,2},{1,3},
 | 
			
		||||
                                      {2,2},{2,3},
 | 
			
		||||
                                            {3,3}};
 | 
			
		||||
 | 
			
		||||
template <class Range>
 | 
			
		||||
void category_test_2(
 | 
			
		||||
    const std::vector<Range>& ranges, unsigned i, unsigned j, std::random_access_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
    typedef Range range;
 | 
			
		||||
    const range& ri = ranges[i];
 | 
			
		||||
    const range& rj = ranges[j];
 | 
			
		||||
 | 
			
		||||
    if (indices[i][0] <= indices[j][0] && indices[i][1] >= indices[j][1])
 | 
			
		||||
        assert(ri.contains(rj));
 | 
			
		||||
 | 
			
		||||
    if (ri.contains(rj))
 | 
			
		||||
        assert((ri & rj) == rj);
 | 
			
		||||
    assert(boost::intersects(ri, rj) == !(ri & rj).empty());
 | 
			
		||||
 | 
			
		||||
    range t1(ri);
 | 
			
		||||
    t1 &= rj;
 | 
			
		||||
    assert(t1 == range(indices[i][0] > indices[j][0] ? ri.start() : rj.start(),
 | 
			
		||||
                       indices[i][1] < indices[j][1] ? ri.finish() : rj.finish()));
 | 
			
		||||
    assert(t1 == (ri & rj));
 | 
			
		||||
    
 | 
			
		||||
    range t2(ri);
 | 
			
		||||
    t2 |= rj;
 | 
			
		||||
    
 | 
			
		||||
    if (ri.empty())
 | 
			
		||||
        assert(t2 == rj);
 | 
			
		||||
    else if (rj.empty())
 | 
			
		||||
        assert(t2 == ri);
 | 
			
		||||
    else
 | 
			
		||||
        assert(t2 == range(indices[i][0] < indices[j][0] ? ri.start() : rj.start(),
 | 
			
		||||
                           indices[i][1] > indices[j][1] ? ri.finish() : rj.finish()));
 | 
			
		||||
    assert(t2 == (ri | rj));
 | 
			
		||||
    if (i == j)
 | 
			
		||||
        assert(ri == rj);
 | 
			
		||||
    
 | 
			
		||||
    if (ri.empty() || rj.empty())
 | 
			
		||||
        assert((ri == rj) == (ri.empty() && rj.empty()));
 | 
			
		||||
    else
 | 
			
		||||
        assert((ri == rj) == (ri.start() == rj.start() && ri.finish() == rj.finish()));
 | 
			
		||||
 | 
			
		||||
    assert((ri == rj) == !(ri != rj));
 | 
			
		||||
 | 
			
		||||
    bool same = ri == rj;
 | 
			
		||||
    bool one_empty = ri.empty() != rj.empty();
 | 
			
		||||
 | 
			
		||||
    std::less<range> less;
 | 
			
		||||
    std::less_equal<range> less_equal;
 | 
			
		||||
    std::greater<range> greater;
 | 
			
		||||
    std::greater_equal<range> greater_equal;
 | 
			
		||||
    
 | 
			
		||||
    if (same)
 | 
			
		||||
    {
 | 
			
		||||
        assert(greater_equal(ri,rj));
 | 
			
		||||
        assert(less_equal(ri,rj));
 | 
			
		||||
        assert(!greater(ri,rj));
 | 
			
		||||
        assert(!less(ri,rj));
 | 
			
		||||
    }
 | 
			
		||||
    else if (one_empty)
 | 
			
		||||
    {
 | 
			
		||||
        const range& empty = ri.empty() ? ri : rj;
 | 
			
		||||
        const range& non_empty = rj.empty() ? ri : rj;
 | 
			
		||||
        
 | 
			
		||||
        assert(less(empty,non_empty));
 | 
			
		||||
        assert(less_equal(empty,non_empty));
 | 
			
		||||
        assert(!greater(empty,non_empty));
 | 
			
		||||
        assert(!greater_equal(empty,non_empty));
 | 
			
		||||
        assert(!less(non_empty,empty));
 | 
			
		||||
        assert(!less_equal(non_empty,empty));
 | 
			
		||||
        assert(greater(non_empty,empty));
 | 
			
		||||
        assert(greater_equal(non_empty,empty));
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        if (indices[i][0] < indices[j][0] ||
 | 
			
		||||
            indices[i][0] == indices[j][0] && indices[i][1] < indices[j][1])
 | 
			
		||||
        {
 | 
			
		||||
            assert(!greater_equal(ri,rj));
 | 
			
		||||
            assert(less(ri,rj));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (indices[i][0] < indices[j][0] ||
 | 
			
		||||
            indices[i][0] == indices[j][0] && indices[i][1] <= indices[j][1])
 | 
			
		||||
        {
 | 
			
		||||
            assert(!greater(ri,rj));
 | 
			
		||||
            assert(less_equal(ri,rj));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (indices[i][0] > indices[j][0] ||
 | 
			
		||||
            indices[i][0] == indices[j][0] && indices[i][1] > indices[j][1])
 | 
			
		||||
        {
 | 
			
		||||
            assert(!less_equal(ri,rj));
 | 
			
		||||
            assert(greater(ri,rj));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (indices[i][0] > indices[j][0] ||
 | 
			
		||||
            indices[i][0] == indices[j][0] && indices[i][1] >= indices[j][1])
 | 
			
		||||
        {
 | 
			
		||||
            assert(!less(ri,rj));
 | 
			
		||||
            assert(greater_equal(ri,rj));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template <class Range>
 | 
			
		||||
void category_test_2(
 | 
			
		||||
    const std::vector<Range>&, unsigned, unsigned, std::forward_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void category_test_2(
 | 
			
		||||
    const std::vector<boost::half_open_range<T> >&, unsigned, unsigned, std::bidirectional_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Range>
 | 
			
		||||
void test_back(Range& x, std::bidirectional_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
    assert(x.back() == boost::prior(x.finish()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Range>
 | 
			
		||||
void test_back(Range& x, std::forward_iterator_tag)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
boost::half_open_range<T> range_identity(const boost::half_open_range<T>& x)
 | 
			
		||||
{
 | 
			
		||||
    return x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void test(T x0, T x1, T x2, T x3)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<boost::half_open_range<T> > ranges;
 | 
			
		||||
    typedef boost::half_open_range<T> range;
 | 
			
		||||
 | 
			
		||||
    T bounds[4] = { x0, x1, x2, x3 };
 | 
			
		||||
 | 
			
		||||
    const std::size_t num_ranges = sizeof(indices)/sizeof(*indices);
 | 
			
		||||
    // test construction
 | 
			
		||||
    for (std::size_t n = 0; n < num_ranges;++n)
 | 
			
		||||
    {
 | 
			
		||||
        T start = bounds[indices[n][0]];
 | 
			
		||||
        T finish = bounds[indices[n][1]];
 | 
			
		||||
        boost::half_open_range<T> r(start, finish);
 | 
			
		||||
        ranges.push_back(r);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // test implicit conversion from std::pair<T,T>
 | 
			
		||||
    range converted = std::pair<T,T>(x0,x0);
 | 
			
		||||
    (void)converted;
 | 
			
		||||
 | 
			
		||||
    // test assignment, equality and inequality
 | 
			
		||||
    range r00 = range(x0, x0);
 | 
			
		||||
    assert(r00 == range(x0,x0));
 | 
			
		||||
    assert(r00 == range(x1,x1)); // empty ranges are all equal
 | 
			
		||||
    if (x3 != x0)
 | 
			
		||||
        assert(r00 != range(x0, x3));
 | 
			
		||||
    r00 = range(x0, x3);
 | 
			
		||||
    assert(r00 == range(x0, x3));
 | 
			
		||||
    if (x3 != x0)
 | 
			
		||||
        assert(r00 != range(x0, x0));
 | 
			
		||||
 | 
			
		||||
    typedef typename range::iterator iterator;
 | 
			
		||||
    typedef typename iterator::iterator_category category;
 | 
			
		||||
    
 | 
			
		||||
    for (unsigned i = 0; i < num_ranges; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        const range& r = ranges[i];
 | 
			
		||||
            
 | 
			
		||||
        // test begin(), end(), basic iteration.
 | 
			
		||||
        unsigned count = 0;
 | 
			
		||||
        for (range::const_iterator p = r.begin(), finish = r.end();
 | 
			
		||||
             p != finish;
 | 
			
		||||
             ++p, ++count)
 | 
			
		||||
        {
 | 
			
		||||
            assert(count < 2100);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // test size(), empty(), front(), back()
 | 
			
		||||
        assert((unsigned)r.size() == count);
 | 
			
		||||
        if (indices[i][0] == indices[i][1])
 | 
			
		||||
            assert(r.empty());
 | 
			
		||||
        if (r.empty())
 | 
			
		||||
            assert(r.size() == 0);
 | 
			
		||||
        if (!r.empty())
 | 
			
		||||
        {
 | 
			
		||||
            assert(r.front() == r.start());
 | 
			
		||||
            test_back(r, category());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            // test swap
 | 
			
		||||
        range r1(r);
 | 
			
		||||
        range r2(x0,x3);
 | 
			
		||||
        const bool same = r1 == r2;
 | 
			
		||||
        r1.swap(r2);
 | 
			
		||||
        assert(r1 == range(x0,x3));
 | 
			
		||||
        assert(r2 == r);
 | 
			
		||||
        if (!same) {
 | 
			
		||||
            assert(r1 != r);
 | 
			
		||||
            assert(r2 != range(x0,x3));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // do individual tests for random-access iterators
 | 
			
		||||
        category_test_1(r, category());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (unsigned j = 0; j < num_ranges; ++j) {
 | 
			
		||||
        for (unsigned k = 0; k < num_ranges; ++k) {
 | 
			
		||||
            category_test_2(ranges, j, k, category());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Integer>
 | 
			
		||||
void test_integer(Integer* = 0) // default arg works around MSVC bug
 | 
			
		||||
{
 | 
			
		||||
    Integer a = 0;
 | 
			
		||||
    Integer b = a + unsigned_random(128 - a);
 | 
			
		||||
    Integer c = b + unsigned_random(128 - b);
 | 
			
		||||
    Integer d = c + unsigned_random(128 - c);
 | 
			
		||||
 | 
			
		||||
    test(a, b, c, d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Container>
 | 
			
		||||
void test_container(Container* = 0)  // default arg works around MSVC bug
 | 
			
		||||
{
 | 
			
		||||
    Container c(unsigned_random(1673));
 | 
			
		||||
 | 
			
		||||
    const typename Container::size_type offset1 = unsigned_random(c.size());
 | 
			
		||||
    const typename Container::size_type offset2 = unsigned_random(c.size() - offset1);
 | 
			
		||||
    typename Container::iterator internal1 = c.begin();
 | 
			
		||||
    std::advance(internal1, offset1);
 | 
			
		||||
    typename Container::iterator internal2 = internal1;
 | 
			
		||||
    std::advance(internal2, offset2);
 | 
			
		||||
    
 | 
			
		||||
    test(c.begin(), internal1, internal2, c.end());
 | 
			
		||||
 | 
			
		||||
    typedef typename Container::const_iterator const_iterator;
 | 
			
		||||
    test(const_iterator(c.begin()),
 | 
			
		||||
         const_iterator(internal1),
 | 
			
		||||
         const_iterator(internal2),
 | 
			
		||||
         const_iterator(c.end()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    // Test the built-in integer types.
 | 
			
		||||
    test_integer<char>();
 | 
			
		||||
    test_integer<unsigned char>();
 | 
			
		||||
    test_integer<signed char>();
 | 
			
		||||
    test_integer<wchar_t>();
 | 
			
		||||
    test_integer<short>();
 | 
			
		||||
    test_integer<unsigned short>();
 | 
			
		||||
    test_integer<int>();
 | 
			
		||||
    test_integer<unsigned int>();
 | 
			
		||||
    test_integer<long>();
 | 
			
		||||
    test_integer<unsigned long>();
 | 
			
		||||
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
 | 
			
		||||
    test_integer<long long>();
 | 
			
		||||
    test_integer<unsigned long long>();
 | 
			
		||||
#endif
 | 
			
		||||
    // Some tests on container iterators, to prove we handle a few different categories
 | 
			
		||||
    test_container<std::vector<int> >();
 | 
			
		||||
    test_container<std::list<int> >();
 | 
			
		||||
#ifndef BOOST_NO_SLIST
 | 
			
		||||
    test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
 | 
			
		||||
#endif
 | 
			
		||||
    // Also prove that we can handle raw pointers.
 | 
			
		||||
    int array[2000];
 | 
			
		||||
    const std::size_t a = 0;
 | 
			
		||||
    const std::size_t b = a + unsigned_random(2000 - a);
 | 
			
		||||
    const std::size_t c = b + unsigned_random(2000 - b);
 | 
			
		||||
    test(array, array+b, array+c, array+2000);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										297
									
								
								in_place_factories.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								in_place_factories.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,297 @@
 | 
			
		||||
<!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=iso-8859-1">
 | 
			
		||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../boost.css">
 | 
			
		||||
<TITLE>Header </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 shceme, 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>
 | 
			
		||||
							
								
								
									
										37
									
								
								include/boost/assert.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								include/boost/assert.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
//
 | 
			
		||||
//  boost/assert.hpp - BOOST_ASSERT(expr)
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 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)
 | 
			
		||||
//
 | 
			
		||||
//  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
 | 
			
		||||
@@ -1,9 +1,10 @@
 | 
			
		||||
//  (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
 | 
			
		||||
//  distribute this software is granted provided this copyright notice appears
 | 
			
		||||
//  in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
//  warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
//  See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp
 | 
			
		||||
//  for full copyright notices.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										69
									
								
								include/boost/checked_delete.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								include/boost/checked_delete.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_CHECKED_DELETE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/checked_delete.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2003 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2003 Daniel Frey
 | 
			
		||||
//  Copyright (c) 2003 Howard Hinnant
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility/checked_delete.html for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// verify that types are complete for increased safety
 | 
			
		||||
 | 
			
		||||
template<class T> inline void checked_delete(T * x)
 | 
			
		||||
{
 | 
			
		||||
    // intentionally complex - simplification causes regressions
 | 
			
		||||
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
 | 
			
		||||
    (void) sizeof(type_must_be_complete);
 | 
			
		||||
    delete x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline void checked_array_delete(T * x)
 | 
			
		||||
{
 | 
			
		||||
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
 | 
			
		||||
    (void) sizeof(type_must_be_complete);
 | 
			
		||||
    delete [] x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> struct checked_deleter
 | 
			
		||||
{
 | 
			
		||||
    typedef void result_type;
 | 
			
		||||
    typedef T * argument_type;
 | 
			
		||||
 | 
			
		||||
    void operator()(T * x) const
 | 
			
		||||
    {
 | 
			
		||||
        // boost:: disables ADL
 | 
			
		||||
        boost::checked_delete(x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> struct checked_array_deleter
 | 
			
		||||
{
 | 
			
		||||
    typedef void result_type;
 | 
			
		||||
    typedef T * argument_type;
 | 
			
		||||
 | 
			
		||||
    void operator()(T * x) const
 | 
			
		||||
    {
 | 
			
		||||
        boost::checked_array_delete(x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
 | 
			
		||||
@@ -1,9 +1,10 @@
 | 
			
		||||
//  (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
 | 
			
		||||
//  distribute this software is granted provided this copyright notice appears
 | 
			
		||||
//  in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
//  warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
//  See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp
 | 
			
		||||
//  for full copyright notices.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										63
									
								
								include/boost/current_function.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								include/boost/current_function.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
#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(__FUNCSIG__)
 | 
			
		||||
 | 
			
		||||
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
 | 
			
		||||
 | 
			
		||||
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
 | 
			
		||||
 | 
			
		||||
# define BOOST_CURRENT_FUNCTION __FUNCTION__
 | 
			
		||||
 | 
			
		||||
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
 | 
			
		||||
 | 
			
		||||
# define BOOST_CURRENT_FUNCTION __FUNC__
 | 
			
		||||
 | 
			
		||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
 | 
			
		||||
 | 
			
		||||
# define BOOST_CURRENT_FUNCTION __func__
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
# define BOOST_CURRENT_FUNCTION "(unknown)"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
 | 
			
		||||
@@ -1,10 +1,9 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Permission to copy, use, modify, sell and
 | 
			
		||||
//  distribute this software is granted provided this copyright notice appears
 | 
			
		||||
//  in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
//  warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
// call_traits: defines typedefs for function usage
 | 
			
		||||
// (see libs/utility/call_traits.htm)
 | 
			
		||||
@@ -22,32 +21,42 @@
 | 
			
		||||
#ifndef BOOST_CONFIG_HPP
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
 | 
			
		||||
#include <boost/type_traits/arithmetic_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
 | 
			
		||||
#include <boost/type_traits/composite_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#include <boost/type_traits/is_arithmetic.hpp>
 | 
			
		||||
#include <boost/type_traits/is_pointer.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost{
 | 
			
		||||
 | 
			
		||||
namespace detail{
 | 
			
		||||
 | 
			
		||||
template <typename T, bool isp, bool b1, bool b2>
 | 
			
		||||
template <typename T, bool small_>
 | 
			
		||||
struct ct_imp2
 | 
			
		||||
{
 | 
			
		||||
   typedef const T& param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct ct_imp2<T, true>
 | 
			
		||||
{
 | 
			
		||||
   typedef const T param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, bool isp, bool b1>
 | 
			
		||||
struct ct_imp
 | 
			
		||||
{
 | 
			
		||||
   typedef const T& param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, bool isp>
 | 
			
		||||
struct ct_imp<T, isp, true, true>
 | 
			
		||||
struct ct_imp<T, isp, true>
 | 
			
		||||
{
 | 
			
		||||
   typedef T const param_type;
 | 
			
		||||
   typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, bool b1, bool b2>
 | 
			
		||||
struct ct_imp<T, true, b1, b2>
 | 
			
		||||
template <typename T, bool b1>
 | 
			
		||||
struct ct_imp<T, true, b1>
 | 
			
		||||
{
 | 
			
		||||
   typedef T const param_type;
 | 
			
		||||
};
 | 
			
		||||
@@ -67,7 +76,11 @@ public:
 | 
			
		||||
   // however compiler bugs prevent this - instead pass three bool's to
 | 
			
		||||
   // ct_imp<T,bool,bool,bool> and add an extra partial specialisation
 | 
			
		||||
   // of ct_imp to handle the logic. (JM)
 | 
			
		||||
   typedef typename detail::ct_imp<T, ::boost::is_pointer<typename remove_const<T>::type>::value, ::boost::is_arithmetic<typename remove_const<T>::type>::value, sizeof(T) <= sizeof(void*)>::param_type param_type;
 | 
			
		||||
   typedef typename detail::ct_imp<
 | 
			
		||||
      T,
 | 
			
		||||
      ::boost::is_pointer<T>::value,
 | 
			
		||||
      ::boost::is_arithmetic<T>::value
 | 
			
		||||
   >::param_type param_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
@@ -79,7 +92,7 @@ struct call_traits<T&>
 | 
			
		||||
   typedef T& param_type;  // hh removed const
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
 | 
			
		||||
#if BOOST_WORKAROUND( __BORLANDC__,  BOOST_TESTED_AT( 0x570 ) )
 | 
			
		||||
// 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
 | 
			
		||||
@@ -109,7 +122,7 @@ struct call_traits<T&const volatile>
 | 
			
		||||
   typedef T& param_type;  // hh removed const
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
 | 
			
		||||
template <typename T, std::size_t N>
 | 
			
		||||
struct call_traits<T [N]>
 | 
			
		||||
{
 | 
			
		||||
@@ -135,6 +148,7 @@ public:
 | 
			
		||||
   typedef const array_type& const_reference;
 | 
			
		||||
   typedef const T* const param_type;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,16 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Permission to copy, use, modify, sell and
 | 
			
		||||
//  distribute this software is granted provided this copyright notice appears
 | 
			
		||||
//  in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
//  warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
// compressed_pair: pair that "compresses" empty members
 | 
			
		||||
// (see libs/utility/compressed_pair.htm)
 | 
			
		||||
//
 | 
			
		||||
// JM changes 25 Jan 2004:
 | 
			
		||||
// For the case where T1 == T2 and both are empty, then first() and second()
 | 
			
		||||
// should return different objects.
 | 
			
		||||
// JM changes 25 Jan 2000:
 | 
			
		||||
// Removed default arguments from compressed_pair_switch to get
 | 
			
		||||
// C++ Builder 4 to accept them
 | 
			
		||||
@@ -19,19 +21,19 @@
 | 
			
		||||
#define BOOST_DETAIL_COMPRESSED_PAIR_HPP
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
 | 
			
		||||
#include <boost/type_traits/object_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_SAME_TRAITS_HPP
 | 
			
		||||
#include <boost/type_traits/same_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BOOST_CALL_TRAITS_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/type_traits/remove_cv.hpp>
 | 
			
		||||
#include <boost/type_traits/is_empty.hpp>
 | 
			
		||||
#include <boost/type_traits/is_same.hpp>
 | 
			
		||||
#include <boost/call_traits.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
class compressed_pair;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// compressed_pair
 | 
			
		||||
 | 
			
		||||
namespace details
 | 
			
		||||
@@ -104,10 +106,10 @@ namespace details
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_(x), second_(y) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(first_param_type x)
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_(x) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(second_param_type y)
 | 
			
		||||
      compressed_pair_imp(second_param_type y)
 | 
			
		||||
         : second_(y) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return first_;}
 | 
			
		||||
@@ -116,10 +118,10 @@ namespace details
 | 
			
		||||
      second_reference       second()       {return second_;}
 | 
			
		||||
      second_const_reference second() const {return second_;}
 | 
			
		||||
 | 
			
		||||
      void swap(compressed_pair_imp& y)
 | 
			
		||||
      void swap(::boost::compressed_pair<T1, T2>& y)
 | 
			
		||||
      {
 | 
			
		||||
         cp_swap(first_, y.first_);
 | 
			
		||||
         cp_swap(second_, y.second_);
 | 
			
		||||
         cp_swap(first_, y.first());
 | 
			
		||||
         cp_swap(second_, y.second());
 | 
			
		||||
      }
 | 
			
		||||
   private:
 | 
			
		||||
      first_type first_;
 | 
			
		||||
@@ -130,7 +132,7 @@ namespace details
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 1>
 | 
			
		||||
      : private T1
 | 
			
		||||
      : private ::boost::remove_cv<T1>::type
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
@@ -147,10 +149,10 @@ namespace details
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_type(x), second_(y) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(first_param_type x)
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_type(x) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(second_param_type y)
 | 
			
		||||
      compressed_pair_imp(second_param_type y)
 | 
			
		||||
         : second_(y) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return *this;}
 | 
			
		||||
@@ -159,10 +161,10 @@ namespace details
 | 
			
		||||
      second_reference       second()       {return second_;}
 | 
			
		||||
      second_const_reference second() const {return second_;}
 | 
			
		||||
 | 
			
		||||
      void swap(compressed_pair_imp& y)
 | 
			
		||||
      void swap(::boost::compressed_pair<T1,T2>& y)
 | 
			
		||||
      {
 | 
			
		||||
         // no need to swap empty base class:
 | 
			
		||||
         cp_swap(second_, y.second_);
 | 
			
		||||
         cp_swap(second_, y.second());
 | 
			
		||||
      }
 | 
			
		||||
   private:
 | 
			
		||||
      second_type second_;
 | 
			
		||||
@@ -172,7 +174,7 @@ namespace details
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 2>
 | 
			
		||||
      : private T2
 | 
			
		||||
      : private ::boost::remove_cv<T2>::type
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
@@ -189,10 +191,10 @@ namespace details
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : second_type(y), first_(x) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(first_param_type x)
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_(x) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(second_param_type y)
 | 
			
		||||
      compressed_pair_imp(second_param_type y)
 | 
			
		||||
         : second_type(y) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return first_;}
 | 
			
		||||
@@ -201,10 +203,10 @@ namespace details
 | 
			
		||||
      second_reference       second()       {return *this;}
 | 
			
		||||
      second_const_reference second() const {return *this;}
 | 
			
		||||
 | 
			
		||||
      void swap(compressed_pair_imp& y)
 | 
			
		||||
      void swap(::boost::compressed_pair<T1,T2>& y)
 | 
			
		||||
      {
 | 
			
		||||
         // no need to swap empty base class:
 | 
			
		||||
         cp_swap(first_, y.first_);
 | 
			
		||||
         cp_swap(first_, y.first());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
@@ -215,8 +217,8 @@ namespace details
 | 
			
		||||
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 3>
 | 
			
		||||
      : private T1,
 | 
			
		||||
        private T2
 | 
			
		||||
      : private ::boost::remove_cv<T1>::type,
 | 
			
		||||
        private ::boost::remove_cv<T2>::type
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
@@ -233,10 +235,10 @@ namespace details
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_type(x), second_type(y) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(first_param_type x)
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_type(x) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(second_param_type y)
 | 
			
		||||
      compressed_pair_imp(second_param_type y)
 | 
			
		||||
         : second_type(y) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return *this;}
 | 
			
		||||
@@ -246,7 +248,7 @@ namespace details
 | 
			
		||||
      second_const_reference second() const {return *this;}
 | 
			
		||||
      //
 | 
			
		||||
      // no need to swap empty bases:
 | 
			
		||||
      void swap(compressed_pair_imp&) {}
 | 
			
		||||
      void swap(::boost::compressed_pair<T1,T2>&) {}
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   // JM
 | 
			
		||||
@@ -255,7 +257,7 @@ namespace details
 | 
			
		||||
   //      but reuses T1 base class for both first() and second().
 | 
			
		||||
   template <class T1, class T2>
 | 
			
		||||
   class compressed_pair_imp<T1, T2, 4>
 | 
			
		||||
      : private T1
 | 
			
		||||
      : private ::boost::remove_cv<T1>::type
 | 
			
		||||
   {
 | 
			
		||||
   public:
 | 
			
		||||
      typedef T1                                                 first_type;
 | 
			
		||||
@@ -269,20 +271,21 @@ namespace details
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp() {}
 | 
			
		||||
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type)
 | 
			
		||||
         : first_type(x) {}
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_type(x), m_second(y) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_type(x) {}
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_type(x), m_second(x) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return *this;}
 | 
			
		||||
      first_const_reference first() const {return *this;}
 | 
			
		||||
 | 
			
		||||
      second_reference       second()       {return *this;}
 | 
			
		||||
      second_const_reference second() const {return *this;}
 | 
			
		||||
      second_reference       second()       {return m_second;}
 | 
			
		||||
      second_const_reference second() const {return m_second;}
 | 
			
		||||
 | 
			
		||||
      void swap(compressed_pair_imp&) {}
 | 
			
		||||
      void swap(::boost::compressed_pair<T1,T2>&) {}
 | 
			
		||||
   private:
 | 
			
		||||
      T2 m_second;
 | 
			
		||||
   };
 | 
			
		||||
 | 
			
		||||
   // 5    T1 == T2 and are not empty:   //JM
 | 
			
		||||
@@ -305,7 +308,7 @@ namespace details
 | 
			
		||||
      compressed_pair_imp(first_param_type x, second_param_type y)
 | 
			
		||||
         : first_(x), second_(y) {}
 | 
			
		||||
 | 
			
		||||
      explicit compressed_pair_imp(first_param_type x)
 | 
			
		||||
      compressed_pair_imp(first_param_type x)
 | 
			
		||||
         : first_(x), second_(x) {}
 | 
			
		||||
 | 
			
		||||
      first_reference       first()       {return first_;}
 | 
			
		||||
@@ -314,10 +317,10 @@ namespace details
 | 
			
		||||
      second_reference       second()       {return second_;}
 | 
			
		||||
      second_const_reference second() const {return second_;}
 | 
			
		||||
 | 
			
		||||
      void swap(compressed_pair_imp<T1, T2, 5>& y)
 | 
			
		||||
      void swap(::boost::compressed_pair<T1, T2>& y)
 | 
			
		||||
      {
 | 
			
		||||
         cp_swap(first_, y.first_);
 | 
			
		||||
         cp_swap(second_, y.second_);
 | 
			
		||||
         cp_swap(first_, y.first());
 | 
			
		||||
         cp_swap(second_, y.second());
 | 
			
		||||
      }
 | 
			
		||||
   private:
 | 
			
		||||
      first_type first_;
 | 
			
		||||
@@ -401,7 +404,10 @@ public:
 | 
			
		||||
 | 
			
		||||
            compressed_pair() : base() {}
 | 
			
		||||
            compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
 | 
			
		||||
   explicit compressed_pair(first_param_type x) : base(x) {}
 | 
			
		||||
#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
 | 
			
		||||
   explicit 
 | 
			
		||||
#endif
 | 
			
		||||
      compressed_pair(first_param_type x) : base(x) {}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       {return base::first();}
 | 
			
		||||
   first_const_reference first() const {return base::first();}
 | 
			
		||||
@@ -409,7 +415,7 @@ public:
 | 
			
		||||
   second_reference       second()       {return base::second();}
 | 
			
		||||
   second_const_reference second() const {return base::second();}
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair& y) { base::swap(y); }
 | 
			
		||||
   void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
@@ -424,5 +430,3 @@ swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,9 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Permission to copy, use, modify, sell and
 | 
			
		||||
//  distribute this software is granted provided this copyright notice appears
 | 
			
		||||
//  in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
//  warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
//
 | 
			
		||||
//  Crippled version for crippled compilers:
 | 
			
		||||
//  see libs/utility/call_traits.htm
 | 
			
		||||
@@ -33,7 +32,7 @@
 | 
			
		||||
 | 
			
		||||
namespace boost{
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
 | 
			
		||||
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
 | 
			
		||||
//
 | 
			
		||||
// use member templates to emulate
 | 
			
		||||
// partial specialisation:
 | 
			
		||||
@@ -64,7 +63,8 @@ struct reference_call_traits
 | 
			
		||||
   typedef T const_reference;
 | 
			
		||||
   typedef T param_type;
 | 
			
		||||
};
 | 
			
		||||
template <bool simple, bool reference>
 | 
			
		||||
 | 
			
		||||
template <bool pointer, bool arithmetic, bool reference>
 | 
			
		||||
struct call_traits_chooser
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
@@ -73,8 +73,9 @@ struct call_traits_chooser
 | 
			
		||||
      typedef standard_call_traits<T> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct call_traits_chooser<true, false>
 | 
			
		||||
struct call_traits_chooser<true, false, false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct rebind
 | 
			
		||||
@@ -82,8 +83,9 @@ struct call_traits_chooser<true, false>
 | 
			
		||||
      typedef simple_call_traits<T> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct call_traits_chooser<false, true>
 | 
			
		||||
struct call_traits_chooser<false, false, true>
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct rebind
 | 
			
		||||
@@ -91,12 +93,50 @@ struct call_traits_chooser<false, true>
 | 
			
		||||
      typedef reference_call_traits<T> type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <bool size_is_small> 
 | 
			
		||||
struct call_traits_sizeof_chooser2
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct small_rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef simple_call_traits<T> small_type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> 
 | 
			
		||||
struct call_traits_sizeof_chooser2<false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct small_rebind
 | 
			
		||||
   {
 | 
			
		||||
      typedef standard_call_traits<T> small_type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct call_traits_chooser<false, true, false>
 | 
			
		||||
{
 | 
			
		||||
   template <class T>
 | 
			
		||||
   struct rebind
 | 
			
		||||
   {
 | 
			
		||||
      enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) };
 | 
			
		||||
      typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser;
 | 
			
		||||
      typedef typename chooser::template small_rebind<T> bound_type;
 | 
			
		||||
      typedef typename bound_type::small_type type;
 | 
			
		||||
   };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct call_traits
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
   typedef detail::call_traits_chooser<(is_pointer<T>::value || is_arithmetic<T>::value) && sizeof(T) <= sizeof(void*), is_reference<T>::value> chooser;
 | 
			
		||||
    typedef detail::call_traits_chooser<
 | 
			
		||||
         ::boost::is_pointer<T>::value,
 | 
			
		||||
         ::boost::is_arithmetic<T>::value, 
 | 
			
		||||
         ::boost::is_reference<T>::value
 | 
			
		||||
      > chooser;
 | 
			
		||||
   typedef typename chooser::template rebind<T> bound_type;
 | 
			
		||||
   typedef typename bound_type::type call_traits_type;
 | 
			
		||||
public:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,16 @@
 | 
			
		||||
//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
 | 
			
		||||
//  Permission to copy, use, modify, sell and
 | 
			
		||||
//  distribute this software is granted provided this copyright notice appears
 | 
			
		||||
//  in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
//  warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
//  Use, modification and distribution are subject to the Boost Software License,
 | 
			
		||||
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt).
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/utility for most recent version including documentation.
 | 
			
		||||
//  see libs/utility/compressed_pair.hpp
 | 
			
		||||
//
 | 
			
		||||
/* Release notes:
 | 
			
		||||
   20 Jan 2001:
 | 
			
		||||
        Fixed obvious bugs (David Abrahams)
 | 
			
		||||
	07 Oct 2000:
 | 
			
		||||
		Added better single argument constructor support.
 | 
			
		||||
   07 Oct 2000:
 | 
			
		||||
      Added better single argument constructor support.
 | 
			
		||||
   03 Oct 2000:
 | 
			
		||||
      Added VC6 support (JM).
 | 
			
		||||
   23rd July 2000:
 | 
			
		||||
@@ -38,7 +37,7 @@
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
 | 
			
		||||
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
 | 
			
		||||
//
 | 
			
		||||
// use member templates to emulate
 | 
			
		||||
// partial specialisation.  Note that due to
 | 
			
		||||
@@ -168,7 +167,7 @@ public:
 | 
			
		||||
   compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
 | 
			
		||||
      : T2(x.second()), _first(x.first()) {}
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
 | 
			
		||||
  // Total weirdness. If the assignment to _first is moved after
 | 
			
		||||
  // the call to the inherited operator=, then this breaks graph/test/graph.cpp
 | 
			
		||||
  // by way of iterator_adaptor.
 | 
			
		||||
@@ -293,22 +292,24 @@ public:
 | 
			
		||||
   typedef typename call_traits<second_type>::const_reference second_const_reference;
 | 
			
		||||
 | 
			
		||||
            compressed_pair_4() : T1() {}
 | 
			
		||||
            compressed_pair_4(first_param_type x, second_param_type) : T1(x) {}
 | 
			
		||||
            compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
 | 
			
		||||
   // only one single argument constructor since T1 == T2
 | 
			
		||||
   explicit compressed_pair_4(first_param_type x) : T1(x) {}
 | 
			
		||||
   explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
 | 
			
		||||
   compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
 | 
			
		||||
      : T1(x.first()){}
 | 
			
		||||
      : T1(x.first()), m_second(x.second()) {}
 | 
			
		||||
 | 
			
		||||
   first_reference       first()       { return *this; }
 | 
			
		||||
   first_const_reference first() const { return *this; }
 | 
			
		||||
 | 
			
		||||
   second_reference       second()       { return *this; }
 | 
			
		||||
   second_const_reference second() const { return *this; }
 | 
			
		||||
   second_reference       second()       { return m_second; }
 | 
			
		||||
   second_const_reference second() const { return m_second; }
 | 
			
		||||
 | 
			
		||||
   void swap(compressed_pair_4& y)
 | 
			
		||||
   {
 | 
			
		||||
      // no need to swap empty base classes:
 | 
			
		||||
   }
 | 
			
		||||
private:
 | 
			
		||||
   T2 m_second;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// T1 == T2, not empty
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
@@ -1,14 +1,22 @@
 | 
			
		||||
//  Boost operators.hpp header file  ----------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright David Abrahams, Jeremy Siek, and Daryle Walker 1999-2001.
 | 
			
		||||
//  Permission to copy, use, modify, sell and distribute this software is
 | 
			
		||||
//  granted provided this copyright notice appears in all copies.  This
 | 
			
		||||
//  software is provided "as is" without express or implied warranty, and
 | 
			
		||||
//  with no claim as to its suitability for any purpose.
 | 
			
		||||
//  (C) Copyright David Abrahams, 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 for most recent version including documentation.
 | 
			
		||||
//  See http://www.boost.org/libs/utility/operators.htm for documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  21 Oct 02 Modified implementation of operators to allow compilers with a
 | 
			
		||||
//            correct named return value optimization (NRVO) to produce optimal
 | 
			
		||||
//            code.  (Daniel Frey)
 | 
			
		||||
//  02 Dec 01 Bug fixed in random_access_iteratable.  (Helmut Zeisel)
 | 
			
		||||
//  28 Sep 01 Factored out iterator operator groups.  (Daryle Walker)
 | 
			
		||||
//  27 Aug 01 'left' form for non commutative operators added;
 | 
			
		||||
//            additional classes for groups of related operators added;
 | 
			
		||||
//            workaround for empty base class optimization
 | 
			
		||||
//            bug of GCC 3.0 (Helmut Zeisel)
 | 
			
		||||
//  25 Jun 01 output_iterator_helper changes: removed default template 
 | 
			
		||||
//            parameters, added support for self-proxying, additional 
 | 
			
		||||
//            documentation and tests (Aleksey Gurtovoy)
 | 
			
		||||
@@ -69,9 +77,10 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/iterator.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(__sgi) && !defined(__GNUC__)
 | 
			
		||||
#pragma set woff 1234
 | 
			
		||||
#   pragma set woff 1234
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC)
 | 
			
		||||
@@ -81,7 +90,14 @@
 | 
			
		||||
namespace boost {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
 | 
			
		||||
#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
 | 
			
		||||
class empty_base {
 | 
			
		||||
  bool dummy; 
 | 
			
		||||
};
 | 
			
		||||
#else
 | 
			
		||||
class empty_base {};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
} // namespace boost
 | 
			
		||||
@@ -136,106 +152,112 @@ struct equality_comparable1 : B
 | 
			
		||||
     friend bool operator!=(const T& x, const T& y) { return !(x == y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct multipliable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator*(T x, const U& y) { return x *= y; }
 | 
			
		||||
     friend T operator*(const U& y, T x) { return 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>            \
 | 
			
		||||
struct NAME##2 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( const T& lhs, const U& rhs )                          \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 | 
			
		||||
  friend T operator OP( const U& lhs, const T& rhs )                          \
 | 
			
		||||
    { T nrv( rhs ); nrv OP##= lhs; return nrv; }                              \
 | 
			
		||||
};                                                                            \
 | 
			
		||||
                                                                              \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>                     \
 | 
			
		||||
struct NAME##1 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( const T& lhs, const T& rhs )                          \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct multipliable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator*(T x, const T& y) { return x *= y; }
 | 
			
		||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )           \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>  \
 | 
			
		||||
struct NAME##2 : B                                                  \
 | 
			
		||||
{                                                                   \
 | 
			
		||||
  friend T operator OP( const T& lhs, const U& rhs )                \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                    \
 | 
			
		||||
};                                                                  \
 | 
			
		||||
                                                                    \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>  \
 | 
			
		||||
struct BOOST_OPERATOR2_LEFT(NAME) : B                               \
 | 
			
		||||
{                                                                   \
 | 
			
		||||
  friend T operator OP( const U& lhs, const T& rhs )                \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                    \
 | 
			
		||||
};                                                                  \
 | 
			
		||||
                                                                    \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>           \
 | 
			
		||||
struct NAME##1 : B                                                  \
 | 
			
		||||
{                                                                   \
 | 
			
		||||
  friend T operator OP( const T& lhs, const T& rhs )                \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                    \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct addable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator+(T x, const U& y) { return x += y; }
 | 
			
		||||
     friend T operator+(const U& y, T x) { return x += y; }
 | 
			
		||||
#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>            \
 | 
			
		||||
struct NAME##2 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; }       \
 | 
			
		||||
  friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; }       \
 | 
			
		||||
};                                                                            \
 | 
			
		||||
                                                                              \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>                     \
 | 
			
		||||
struct NAME##1 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; }       \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct addable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator+(T x, const T& y) { return x += y; }
 | 
			
		||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>      \
 | 
			
		||||
struct NAME##2 : B                                                      \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
 | 
			
		||||
};                                                                      \
 | 
			
		||||
                                                                        \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>      \
 | 
			
		||||
struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( const U& lhs, const T& rhs )                    \
 | 
			
		||||
    { return T( lhs ) OP##= rhs; }                                      \
 | 
			
		||||
};                                                                      \
 | 
			
		||||
                                                                        \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>               \
 | 
			
		||||
struct NAME##1 : B                                                      \
 | 
			
		||||
{                                                                       \
 | 
			
		||||
  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct subtractable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator-(T x, const U& y) { return x -= y; }
 | 
			
		||||
};
 | 
			
		||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct subtractable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator-(T x, const T& y) { return x -= y; }
 | 
			
		||||
};
 | 
			
		||||
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, | )
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct dividable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator/(T x, const U& y) { return x /= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct dividable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator/(T x, const T& y) { return x /= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct modable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator%(T x, const U& y) { return x %= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct modable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator%(T x, const T& y) { return x %= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct xorable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator^(T x, const U& y) { return x ^= y; }
 | 
			
		||||
     friend T operator^(const U& y, T x) { return x ^= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct xorable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator^(T x, const T& y) { return x ^= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct andable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator&(T x, const U& y) { return x &= y; }
 | 
			
		||||
     friend T operator&(const U& y, T x) { return x &= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct andable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator&(T x, const T& y) { return x &= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct orable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator|(T x, const U& y) { return x |= y; }
 | 
			
		||||
     friend T operator|(const U& y, T x) { return x |= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct orable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator|(T x, const T& y) { return x |= y; }
 | 
			
		||||
};
 | 
			
		||||
#undef BOOST_BINARY_OPERATOR_COMMUTATIVE
 | 
			
		||||
#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
 | 
			
		||||
#undef BOOST_OPERATOR2_LEFT
 | 
			
		||||
 | 
			
		||||
//  incrementable and decrementable contributed by Jeremy Siek
 | 
			
		||||
 | 
			
		||||
@@ -244,9 +266,9 @@ struct incrementable : B
 | 
			
		||||
{
 | 
			
		||||
  friend T operator++(T& x, int)
 | 
			
		||||
  {
 | 
			
		||||
    incrementable_type tmp(x);
 | 
			
		||||
    incrementable_type nrv(x);
 | 
			
		||||
    ++x;
 | 
			
		||||
    return tmp;
 | 
			
		||||
    return nrv;
 | 
			
		||||
  }
 | 
			
		||||
private: // The use of this typedef works around a Borland bug
 | 
			
		||||
  typedef T incrementable_type;
 | 
			
		||||
@@ -257,9 +279,9 @@ struct decrementable : B
 | 
			
		||||
{
 | 
			
		||||
  friend T operator--(T& x, int)
 | 
			
		||||
  {
 | 
			
		||||
    decrementable_type tmp(x);
 | 
			
		||||
    decrementable_type nrv(x);
 | 
			
		||||
    --x;
 | 
			
		||||
    return tmp;
 | 
			
		||||
    return nrv;
 | 
			
		||||
  }
 | 
			
		||||
private: // The use of this typedef works around a Borland bug
 | 
			
		||||
  typedef T decrementable_type;
 | 
			
		||||
@@ -286,30 +308,46 @@ struct indexable : B
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//  More operator classes (contributed by Daryle Walker) --------------------//
 | 
			
		||||
//  (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct left_shiftable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator<<(T x, const U& y) { return x <<= y; }
 | 
			
		||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
#define BOOST_BINARY_OPERATOR( NAME, OP )                                     \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>            \
 | 
			
		||||
struct NAME##2 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( const T& lhs, const U& rhs )                          \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 | 
			
		||||
};                                                                            \
 | 
			
		||||
                                                                              \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>                     \
 | 
			
		||||
struct NAME##1 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( const T& lhs, const T& rhs )                          \
 | 
			
		||||
    { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct left_shiftable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator<<(T x, const T& y) { return x <<= y; }
 | 
			
		||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
#define BOOST_BINARY_OPERATOR( NAME, OP )                                     \
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>            \
 | 
			
		||||
struct NAME##2 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; }       \
 | 
			
		||||
};                                                                            \
 | 
			
		||||
                                                                              \
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>                     \
 | 
			
		||||
struct NAME##1 : B                                                            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
  friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; }       \
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct right_shiftable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator>>(T x, const U& y) { return x >>= y; }
 | 
			
		||||
};
 | 
			
		||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct right_shiftable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator>>(T x, const T& y) { return x >>= y; }
 | 
			
		||||
};
 | 
			
		||||
BOOST_BINARY_OPERATOR( left_shiftable, << )
 | 
			
		||||
BOOST_BINARY_OPERATOR( right_shiftable, >> )
 | 
			
		||||
 | 
			
		||||
#undef BOOST_BINARY_OPERATOR
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct equivalent2 : B
 | 
			
		||||
@@ -463,12 +501,125 @@ struct shiftable1
 | 
			
		||||
    , right_shiftable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct ring_operators2
 | 
			
		||||
    : additive2<T, U
 | 
			
		||||
    , subtractable2_left<T, U
 | 
			
		||||
    , multipliable2<T, U, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct ring_operators1
 | 
			
		||||
    : additive1<T
 | 
			
		||||
    , multipliable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct ordered_ring_operators2
 | 
			
		||||
    : ring_operators2<T, U
 | 
			
		||||
    , totally_ordered2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct ordered_ring_operators1
 | 
			
		||||
    : ring_operators1<T
 | 
			
		||||
    , totally_ordered1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct field_operators2
 | 
			
		||||
    : ring_operators2<T, U
 | 
			
		||||
    , dividable2<T, U
 | 
			
		||||
    , dividable2_left<T, U, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct field_operators1
 | 
			
		||||
    : ring_operators1<T
 | 
			
		||||
    , dividable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct ordered_field_operators2
 | 
			
		||||
    : field_operators2<T, U
 | 
			
		||||
    , totally_ordered2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct ordered_field_operators1
 | 
			
		||||
    : field_operators1<T
 | 
			
		||||
    , totally_ordered1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct euclidian_ring_operators2
 | 
			
		||||
    : ring_operators2<T, U
 | 
			
		||||
    , dividable2<T, U
 | 
			
		||||
    , dividable2_left<T, U
 | 
			
		||||
    , modable2<T, U
 | 
			
		||||
    , modable2_left<T, U, B
 | 
			
		||||
      > > > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct euclidian_ring_operators1
 | 
			
		||||
    : ring_operators1<T
 | 
			
		||||
    , dividable1<T
 | 
			
		||||
    , modable1<T, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct ordered_euclidian_ring_operators2
 | 
			
		||||
    : totally_ordered2<T, U
 | 
			
		||||
    , euclidian_ring_operators2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct ordered_euclidian_ring_operators1
 | 
			
		||||
    : totally_ordered1<T
 | 
			
		||||
    , euclidian_ring_operators1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
      
 | 
			
		||||
template <class T, class P, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct input_iteratable
 | 
			
		||||
    : equality_comparable1<T
 | 
			
		||||
    , incrementable<T
 | 
			
		||||
    , dereferenceable<T, P, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct output_iteratable
 | 
			
		||||
    : incrementable<T, B
 | 
			
		||||
      > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class P, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct forward_iteratable
 | 
			
		||||
    : input_iteratable<T, P, B
 | 
			
		||||
      > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class P, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct bidirectional_iteratable
 | 
			
		||||
    : forward_iteratable<T, P
 | 
			
		||||
    , decrementable<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
//  To avoid repeated derivation from equality_comparable,
 | 
			
		||||
//  which is an indirect base class of bidirectional_iterable,
 | 
			
		||||
//  random_access_iteratable must not be derived from totally_ordered1
 | 
			
		||||
//  but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
 | 
			
		||||
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct random_access_iteratable
 | 
			
		||||
    : bidirectional_iteratable<T, P
 | 
			
		||||
    , less_than_comparable1<T
 | 
			
		||||
    , additive2<T, D
 | 
			
		||||
    , indexable<T, D, R, B
 | 
			
		||||
      > > > > {};
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
} // namespace boost
 | 
			
		||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE3 -
 | 
			
		||||
// 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
 | 
			
		||||
@@ -479,6 +630,7 @@ struct shiftable1
 | 
			
		||||
#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)
 | 
			
		||||
@@ -489,6 +641,7 @@ struct shiftable1
 | 
			
		||||
 | 
			
		||||
     // 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;
 | 
			
		||||
@@ -497,6 +650,10 @@ struct shiftable1
 | 
			
		||||
 | 
			
		||||
     // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
 | 
			
		||||
     // from working, we are forced to use inheritance for that compiler.
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE4(template_name)                                          \
 | 
			
		||||
     template <class T, class U, class V, class W, class B = ::boost::detail::empty_base>  \
 | 
			
		||||
     struct template_name : ::template_name<T, U, V, W, B> {};
 | 
			
		||||
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE3(template_name)                                 \
 | 
			
		||||
     template <class T, class U, class V, class B = ::boost::detail::empty_base>  \
 | 
			
		||||
     struct template_name : ::template_name<T, U, V, B> {};
 | 
			
		||||
@@ -517,7 +674,7 @@ struct shiftable1
 | 
			
		||||
// 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
 | 
			
		||||
// neccessary.
 | 
			
		||||
// necessary.
 | 
			
		||||
//
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
@@ -542,7 +699,16 @@ template<class T> struct is_chained_base {
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
// Import a 3-type-argument operator template into boost (if neccessary) and
 | 
			
		||||
// 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)                              \
 | 
			
		||||
@@ -551,7 +717,7 @@ template<class T> struct is_chained_base {
 | 
			
		||||
    typedef ::boost::detail::true_t value;                            \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// Import a 2-type-argument operator template into boost (if neccessary) and
 | 
			
		||||
// Import a 2-type-argument operator template into boost (if necessary) and
 | 
			
		||||
// provide a specialization of 'is_chained_base<>' for it.
 | 
			
		||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2)                  \
 | 
			
		||||
  BOOST_IMPORT_TEMPLATE2(template_name2)                           \
 | 
			
		||||
@@ -560,7 +726,7 @@ template<class T> struct is_chained_base {
 | 
			
		||||
    typedef ::boost::detail::true_t value;                         \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// Import a 1-type-argument operator template into boost (if neccessary) and
 | 
			
		||||
// 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)                           \
 | 
			
		||||
@@ -610,6 +776,8 @@ 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) \
 | 
			
		||||
@@ -632,8 +800,11 @@ 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)
 | 
			
		||||
@@ -658,14 +829,27 @@ 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.
 | 
			
		||||
@@ -699,20 +883,18 @@ template <class T,
 | 
			
		||||
          class P = V const *,
 | 
			
		||||
          class R = V const &>
 | 
			
		||||
struct input_iterator_helper
 | 
			
		||||
  : equality_comparable1<T
 | 
			
		||||
  , incrementable<T
 | 
			
		||||
  , dereferenceable<T, P
 | 
			
		||||
  : input_iteratable<T, P
 | 
			
		||||
  , boost::iterator<std::input_iterator_tag, V, D, P, R
 | 
			
		||||
    > > > > {};
 | 
			
		||||
    > > {};
 | 
			
		||||
 | 
			
		||||
template<class Derived>
 | 
			
		||||
template<class T>
 | 
			
		||||
struct output_iterator_helper
 | 
			
		||||
  : boost::incrementable<Derived
 | 
			
		||||
  : output_iteratable<T
 | 
			
		||||
  , boost::iterator<std::output_iterator_tag, void, void, void, void
 | 
			
		||||
  > >
 | 
			
		||||
{
 | 
			
		||||
  Derived& operator*()  { return static_cast<Derived&>(*this); }
 | 
			
		||||
  Derived& operator++() { return static_cast<Derived&>(*this); }
 | 
			
		||||
  T& operator*()  { return static_cast<T&>(*this); }
 | 
			
		||||
  T& operator++() { return static_cast<T&>(*this); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
@@ -721,11 +903,9 @@ template <class T,
 | 
			
		||||
          class P = V*,
 | 
			
		||||
          class R = V&>
 | 
			
		||||
struct forward_iterator_helper
 | 
			
		||||
  : equality_comparable1<T
 | 
			
		||||
  , incrementable<T
 | 
			
		||||
  , dereferenceable<T, P
 | 
			
		||||
  : forward_iteratable<T, P
 | 
			
		||||
  , boost::iterator<std::forward_iterator_tag, V, D, P, R
 | 
			
		||||
    > > > > {};
 | 
			
		||||
    > > {};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V,
 | 
			
		||||
@@ -733,11 +913,9 @@ template <class T,
 | 
			
		||||
          class P = V*,
 | 
			
		||||
          class R = V&>
 | 
			
		||||
struct bidirectional_iterator_helper
 | 
			
		||||
  : equality_comparable1<T
 | 
			
		||||
  , unit_steppable<T
 | 
			
		||||
  , dereferenceable<T, P
 | 
			
		||||
  : bidirectional_iteratable<T, P
 | 
			
		||||
  , boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
 | 
			
		||||
    > > > > {};
 | 
			
		||||
    > > {};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V, 
 | 
			
		||||
@@ -745,13 +923,9 @@ template <class T,
 | 
			
		||||
          class P = V*,
 | 
			
		||||
          class R = V&>
 | 
			
		||||
struct random_access_iterator_helper
 | 
			
		||||
  : totally_ordered1<T
 | 
			
		||||
  , unit_steppable<T
 | 
			
		||||
  , dereferenceable<T, P
 | 
			
		||||
  , additive2<T, D
 | 
			
		||||
  , indexable<T, D, R
 | 
			
		||||
  : 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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										177
									
								
								include/boost/ref.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								include/boost/ref.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
#ifndef BOOST_REF_HPP_INCLUDED
 | 
			
		||||
#define BOOST_REF_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/utility/addressof.hpp>
 | 
			
		||||
#include <boost/mpl/bool.hpp>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  ref.hpp - ref/cref, useful helper functions
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (C) 1999, 2000 Jaakko J<>rvi (jaakko.jarvi@cs.utu.fi)
 | 
			
		||||
//  Copyright (C) 2001, 2002 Peter Dimov
 | 
			
		||||
//  Copyright (C) 2002 David Abrahams
 | 
			
		||||
//
 | 
			
		||||
// 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_MSVC < 1300)
 | 
			
		||||
 | 
			
		||||
    explicit reference_wrapper(T& t): t_(&t) {}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    operator T& () const { return *t_; }
 | 
			
		||||
 | 
			
		||||
    T& get() const { return *t_; }
 | 
			
		||||
 | 
			
		||||
    T* get_pointer() const { return t_; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T* t_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)
 | 
			
		||||
#  define BOOST_REF_CONST
 | 
			
		||||
# else
 | 
			
		||||
#  define BOOST_REF_CONST const
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t)
 | 
			
		||||
{ 
 | 
			
		||||
    return reference_wrapper<T>(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const & t)
 | 
			
		||||
{
 | 
			
		||||
    return reference_wrapper<T const>(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# undef BOOST_REF_CONST
 | 
			
		||||
 | 
			
		||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class is_reference_wrapper
 | 
			
		||||
    : public mpl::false_
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class unwrap_reference
 | 
			
		||||
{
 | 
			
		||||
 public:
 | 
			
		||||
    typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#  define AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(X) \
 | 
			
		||||
template<typename T> \
 | 
			
		||||
class is_reference_wrapper< X > \
 | 
			
		||||
    : public mpl::true_ \
 | 
			
		||||
{ \
 | 
			
		||||
}; \
 | 
			
		||||
\
 | 
			
		||||
template<typename T> \
 | 
			
		||||
class unwrap_reference< X > \
 | 
			
		||||
{ \
 | 
			
		||||
 public: \
 | 
			
		||||
    typedef T type; \
 | 
			
		||||
}; \
 | 
			
		||||
/**/
 | 
			
		||||
 | 
			
		||||
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T>)
 | 
			
		||||
#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
 | 
			
		||||
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const)
 | 
			
		||||
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> volatile)
 | 
			
		||||
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const volatile)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#  undef AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF
 | 
			
		||||
 | 
			
		||||
# else // no partial specialization
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#include <boost/type.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
  typedef char (&yes_reference_wrapper_t)[1];
 | 
			
		||||
  typedef char (&no_reference_wrapper_t)[2];
 | 
			
		||||
      
 | 
			
		||||
  no_reference_wrapper_t is_reference_wrapper_test(...);
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
  yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper<T> >);
 | 
			
		||||
 | 
			
		||||
  template<bool wrapped>
 | 
			
		||||
  struct reference_unwrapper
 | 
			
		||||
  {
 | 
			
		||||
      template <class T>
 | 
			
		||||
      struct apply
 | 
			
		||||
      {
 | 
			
		||||
          typedef T type;
 | 
			
		||||
      };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<>
 | 
			
		||||
  struct reference_unwrapper<true>
 | 
			
		||||
  {
 | 
			
		||||
      template <class T>
 | 
			
		||||
      struct apply
 | 
			
		||||
      {
 | 
			
		||||
          typedef typename T::type type;
 | 
			
		||||
      };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class is_reference_wrapper
 | 
			
		||||
{
 | 
			
		||||
 public:
 | 
			
		||||
    BOOST_STATIC_CONSTANT(
 | 
			
		||||
        bool, value = (
 | 
			
		||||
             sizeof(detail::is_reference_wrapper_test(type<T>()))
 | 
			
		||||
            == sizeof(detail::yes_reference_wrapper_t)));
 | 
			
		||||
    
 | 
			
		||||
    typedef ::boost::mpl::bool_<value> type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
class unwrap_reference
 | 
			
		||||
    : public detail::reference_unwrapper<
 | 
			
		||||
        is_reference_wrapper<T>::value
 | 
			
		||||
      >::template apply<T>
 | 
			
		||||
{};
 | 
			
		||||
 | 
			
		||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_REF_HPP_INCLUDED
 | 
			
		||||
@@ -1,119 +1,19 @@
 | 
			
		||||
//  boost utility.hpp header file  -------------------------------------------//
 | 
			
		||||
//  Boost utility.hpp header file  -------------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
 | 
			
		||||
//  and distribute this software is granted provided this copyright
 | 
			
		||||
//  notice appears in all copies. This software is provided "as is" without
 | 
			
		||||
//  express or implied warranty, and with no claim as to its suitability for
 | 
			
		||||
//  any purpose.
 | 
			
		||||
//  Copyright 1999-2003 Aleksey Gurtovoy.  Use, modification, and distribution are
 | 
			
		||||
//  subject to the Boost Software License, Version 1.0.  (See accompanying file
 | 
			
		||||
//  LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Classes appear in alphabetical order
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  21 May 01  checked_delete() and checked_array_delete() added (Beman Dawes,
 | 
			
		||||
//             suggested by Dave Abrahams, generalizing idea from Vladimir Prus)
 | 
			
		||||
//  21 May 01  made next() and prior() inline (Beman Dawes)  
 | 
			
		||||
//  26 Jan 00  protected noncopyable destructor added (Miki Jovanovic)
 | 
			
		||||
//  10 Dec 99  next() and prior() templates added (Dave Abrahams)
 | 
			
		||||
//  30 Aug 99  moved cast templates to cast.hpp (Beman Dawes)
 | 
			
		||||
//   3 Aug 99  cast templates added
 | 
			
		||||
//  20 Jul 99  name changed to utility.hpp 
 | 
			
		||||
//   9 Jun 99  protected noncopyable default ctor
 | 
			
		||||
//   2 Jun 99  Initial Version. Class noncopyable only contents (Dave Abrahams)
 | 
			
		||||
//  See <http://www.boost.org/libs/utility/> for the library's home page.
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_UTILITY_HPP
 | 
			
		||||
#define BOOST_UTILITY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>        // broken compiler workarounds 
 | 
			
		||||
#include <boost/static_assert.hpp> 
 | 
			
		||||
#include <cstddef>                 // for size_t
 | 
			
		||||
#include <utility>                 // for std::pair
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
//  checked_delete() and checked_array_delete()  -----------------------------//
 | 
			
		||||
 | 
			
		||||
    // verify that types are complete for increased safety
 | 
			
		||||
 | 
			
		||||
    template< typename T >
 | 
			
		||||
    inline void checked_delete(T * x)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_ASSERT( sizeof(T) != 0 ); // assert type complete at point
 | 
			
		||||
                                               // of instantiation
 | 
			
		||||
        delete x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< typename T >
 | 
			
		||||
    inline void checked_array_delete(T  * x)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_ASSERT( sizeof(T) != 0 ); // assert type complete at point
 | 
			
		||||
                                               // of instantiation
 | 
			
		||||
        delete [] x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  next() and prior() template functions  -----------------------------------//
 | 
			
		||||
 | 
			
		||||
    //  Helper functions for classes like bidirectional iterators not supporting
 | 
			
		||||
    //  operator+ and operator-.
 | 
			
		||||
    //
 | 
			
		||||
    //  Usage:
 | 
			
		||||
    //    const std::list<T>::iterator p = get_some_iterator();
 | 
			
		||||
    //    const std::list<T>::iterator prev = boost::prior(p);
 | 
			
		||||
 | 
			
		||||
    //  Contributed by Dave Abrahams
 | 
			
		||||
 | 
			
		||||
    template <class T>
 | 
			
		||||
    inline T next(T x) { return ++x; }
 | 
			
		||||
 | 
			
		||||
    template <class T>
 | 
			
		||||
    inline T prior(T x) { return --x; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  class noncopyable  -------------------------------------------------------//
 | 
			
		||||
 | 
			
		||||
    //  Private copy constructor and copy assignment ensure classes derived from
 | 
			
		||||
    //  class noncopyable cannot be copied.
 | 
			
		||||
 | 
			
		||||
    //  Contributed by Dave Abrahams
 | 
			
		||||
 | 
			
		||||
    class noncopyable
 | 
			
		||||
    {
 | 
			
		||||
    protected:
 | 
			
		||||
        noncopyable(){}
 | 
			
		||||
        ~noncopyable(){}
 | 
			
		||||
    private:  // emphasize the following members are private
 | 
			
		||||
        noncopyable( const noncopyable& );
 | 
			
		||||
        const noncopyable& operator=( const noncopyable& );
 | 
			
		||||
    }; // noncopyable
 | 
			
		||||
 | 
			
		||||
//  class tied  -------------------------------------------------------//
 | 
			
		||||
 | 
			
		||||
    // A helper for conveniently assigning the two values from a pair
 | 
			
		||||
    // into separate variables. The idea for this comes from Jaakko J<>rvi's
 | 
			
		||||
    // Binder/Lambda Library.
 | 
			
		||||
 | 
			
		||||
    // Constributed by Jeremy Siek
 | 
			
		||||
 | 
			
		||||
    template <class A, class B>
 | 
			
		||||
    class tied {
 | 
			
		||||
    public:
 | 
			
		||||
      inline tied(A& a, B& b) : _a(a), _b(b) { }
 | 
			
		||||
      template <class U, class V>
 | 
			
		||||
      inline tied& operator=(const std::pair<U,V>& p) {
 | 
			
		||||
        _a = p.first;
 | 
			
		||||
        _b = p.second;
 | 
			
		||||
        return *this;
 | 
			
		||||
      }
 | 
			
		||||
    protected:
 | 
			
		||||
      A& _a;
 | 
			
		||||
      B& _b;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template <class A, class B>
 | 
			
		||||
    inline tied<A,B> tie(A& a, B& b) { return tied<A,B>(a, b); }
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
#include <boost/utility/addressof.hpp>
 | 
			
		||||
#include <boost/utility/base_from_member.hpp>  
 | 
			
		||||
#include <boost/utility/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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								include/boost/utility/detail/in_place_factory_prefix.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								include/boost/utility/detail/in_place_factory_prefix.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
// 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_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP
 | 
			
		||||
#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.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/cat.hpp>
 | 
			
		||||
#include <boost/preprocessor/arithmetic/inc.hpp>
 | 
			
		||||
#include <boost/preprocessor/punctuation/paren.hpp>
 | 
			
		||||
#include <boost/preprocessor/facilities/empty.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_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_ARG(z,n,_)  BOOST_PP_CAT(m_a,n)
 | 
			
		||||
 | 
			
		||||
#define BOOST_MAX_INPLACE_FACTORY_ARITY 10
 | 
			
		||||
 | 
			
		||||
#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_25AGO2003_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.
 | 
			
		||||
//
 | 
			
		||||
// 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_25AGO2003_HPP
 | 
			
		||||
#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_25AGO2003_HPP
 | 
			
		||||
 | 
			
		||||
#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT
 | 
			
		||||
#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL
 | 
			
		||||
#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_ARG
 | 
			
		||||
#undef BOOST_MAX_INPLACE_FACTORY_ARITY
 | 
			
		||||
 | 
			
		||||
#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										86
									
								
								include/boost/utility/detail/result_of_iterate.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								include/boost/utility/detail/result_of_iterate.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
// 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)>
 | 
			
		||||
    : detail::result_of<F, F(BOOST_RESULT_OF_ARGS)> {};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
template<typename R,  typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
 | 
			
		||||
         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
 | 
			
		||||
struct result_of<R (*)(BOOST_RESULT_OF_ARGS), FArgs>
 | 
			
		||||
{
 | 
			
		||||
  typedef R type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename R,  typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
 | 
			
		||||
         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
 | 
			
		||||
struct result_of<R (&)(BOOST_RESULT_OF_ARGS), FArgs>
 | 
			
		||||
{
 | 
			
		||||
  typedef R type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#undef BOOST_RESULT_OF_ARGS
 | 
			
		||||
 | 
			
		||||
#if BOOST_PP_ITERATION() > 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
 | 
			
		||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
 | 
			
		||||
         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
 | 
			
		||||
struct result_of<R (T0::*)
 | 
			
		||||
                     (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
 | 
			
		||||
                 FArgs>
 | 
			
		||||
{
 | 
			
		||||
  typedef R type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
 | 
			
		||||
         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
 | 
			
		||||
struct result_of<R (T0::*)
 | 
			
		||||
                     (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
 | 
			
		||||
                     const,
 | 
			
		||||
                 FArgs>
 | 
			
		||||
{
 | 
			
		||||
  typedef R type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
 | 
			
		||||
         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
 | 
			
		||||
struct result_of<R (T0::*)
 | 
			
		||||
                     (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
 | 
			
		||||
                     volatile,
 | 
			
		||||
                 FArgs>
 | 
			
		||||
{
 | 
			
		||||
  typedef R type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
 | 
			
		||||
         BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
 | 
			
		||||
struct result_of<R (T0::*)
 | 
			
		||||
                     (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
 | 
			
		||||
                     const volatile,
 | 
			
		||||
                 FArgs>
 | 
			
		||||
{
 | 
			
		||||
  typedef R type;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										119
									
								
								include/boost/utility/enable_if.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								include/boost/utility/enable_if.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
// Boost enable_if library
 | 
			
		||||
 | 
			
		||||
// Copyright 2003 <20> The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification, and distribution is subject to the Boost Software
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//    Authors: Jaakko J<>rvi (jajarvi at osl.iu.edu)
 | 
			
		||||
//             Jeremiah Willcock (jewillco at osl.iu.edu)
 | 
			
		||||
//             Andrew Lumsdaine (lums at osl.iu.edu)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_UTILITY_ENABLE_IF_HPP
 | 
			
		||||
#define BOOST_UTILITY_ENABLE_IF_HPP
 | 
			
		||||
 | 
			
		||||
#include "boost/config.hpp"
 | 
			
		||||
 | 
			
		||||
// Even the definition of enable_if causes problems on some compilers,
 | 
			
		||||
// so it's macroed out for all compilers that do not support SFINAE
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_SFINAE
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
  template <bool B, class T = void>
 | 
			
		||||
  struct enable_if_c {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct enable_if_c<false, T> {};
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = void> 
 | 
			
		||||
  struct enable_if : public enable_if_c<Cond::value, T> {};
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T>
 | 
			
		||||
  struct lazy_enable_if_c {
 | 
			
		||||
    typedef typename T::type type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct lazy_enable_if_c<false, T> {};
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T> 
 | 
			
		||||
  struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = void>
 | 
			
		||||
  struct disable_if_c {
 | 
			
		||||
    typedef T type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct disable_if_c<true, T> {};
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = void> 
 | 
			
		||||
  struct disable_if : public disable_if_c<Cond::value, T> {};
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T>
 | 
			
		||||
  struct lazy_disable_if_c {
 | 
			
		||||
    typedef typename T::type type;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class T>
 | 
			
		||||
  struct lazy_disable_if_c<true, T> {};
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T> 
 | 
			
		||||
  struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
  namespace detail { typedef void enable_if_default_T; }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct enable_if_does_not_work_on_this_compiler;
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = detail::enable_if_default_T>
 | 
			
		||||
  struct enable_if_c : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct disable_if_c : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <bool B, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct enable_if : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct disable_if : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct lazy_enable_if : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
  template <class Cond, class T = detail::enable_if_default_T> 
 | 
			
		||||
  struct lazy_disable_if : enable_if_does_not_work_on_this_compiler<T>
 | 
			
		||||
  { };
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_SFINAE
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										58
									
								
								include/boost/utility/in_place_factory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								include/boost/utility/in_place_factory.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
// 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_INPLACE_FACTORY_25AGO2003_HPP
 | 
			
		||||
#define BOOST_UTILITY_INPLACE_FACTORY_25AGO2003_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/utility/detail/in_place_factory_prefix.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/type.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
class in_place_factory_base {} ;
 | 
			
		||||
 | 
			
		||||
#define BOOST_DEFINE_INPLACE_FACTORY_CLASS(z,n,_) \
 | 
			
		||||
template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \
 | 
			
		||||
class BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) : public in_place_factory_base \
 | 
			
		||||
{ \
 | 
			
		||||
public: \
 | 
			
		||||
\
 | 
			
		||||
  BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A,const& a) ) \
 | 
			
		||||
    : \
 | 
			
		||||
    BOOST_PP_ENUM( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _ ) \
 | 
			
		||||
  {} \
 | 
			
		||||
\
 | 
			
		||||
  template<class T> \
 | 
			
		||||
  void apply ( void* address BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T) ) const \
 | 
			
		||||
  { \
 | 
			
		||||
    new ( address ) T ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), m_a ) ) ; \
 | 
			
		||||
  } \
 | 
			
		||||
\
 | 
			
		||||
  BOOST_PP_REPEAT( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) \
 | 
			
		||||
} ; \
 | 
			
		||||
\
 | 
			
		||||
template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \
 | 
			
		||||
BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) < BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \
 | 
			
		||||
in_place ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A, const& a) ) \
 | 
			
		||||
{ \
 | 
			
		||||
  return BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) < BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \
 | 
			
		||||
           ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), a ) ) ; \
 | 
			
		||||
} ; \
 | 
			
		||||
 | 
			
		||||
BOOST_PP_REPEAT( BOOST_MAX_INPLACE_FACTORY_ARITY, BOOST_DEFINE_INPLACE_FACTORY_CLASS, BOOST_PP_EMPTY() )
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#include <boost/utility/detail/in_place_factory_suffix.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										66
									
								
								include/boost/utility/result_of.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								include/boost/utility/result_of.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
// Boost result_of library
 | 
			
		||||
 | 
			
		||||
//  Copyright Douglas Gregor 2004. Use, modification and
 | 
			
		||||
//  distribution is subject to the Boost Software License, Version
 | 
			
		||||
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
// For more information, see http://www.boost.org/libs/utility
 | 
			
		||||
#ifndef BOOST_RESULT_OF_HPP
 | 
			
		||||
#define BOOST_RESULT_OF_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/type_traits/ice.hpp>
 | 
			
		||||
#include <boost/type.hpp>
 | 
			
		||||
#include <boost/preprocessor.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/mpl/has_xxx.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
 | 
			
		||||
#  define BOOST_RESULT_OF_NUM_ARGS 10
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
template<typename F> struct result_of;
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
 | 
			
		||||
 | 
			
		||||
template<typename F, typename FArgs, bool HasResultType> struct get_result_of;
 | 
			
		||||
 | 
			
		||||
template<typename F, typename FArgs>
 | 
			
		||||
struct get_result_of<F, FArgs, true>
 | 
			
		||||
{
 | 
			
		||||
  typedef typename F::result_type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename F, typename FArgs>
 | 
			
		||||
struct get_result_of<F, FArgs, false>
 | 
			
		||||
{
 | 
			
		||||
  typedef typename F::template result<FArgs>::type type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename F>
 | 
			
		||||
struct get_result_of<F, F(void), false>
 | 
			
		||||
{
 | 
			
		||||
  typedef void type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename F, typename FArgs>
 | 
			
		||||
struct result_of : get_result_of<F, FArgs, (has_result_type<F>::value)> {};
 | 
			
		||||
 | 
			
		||||
} // end namespace detail
 | 
			
		||||
 | 
			
		||||
#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
 | 
			
		||||
#include BOOST_PP_ITERATE()
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#  define BOOST_NO_RESULT_OF 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_RESULT_OF_HPP
 | 
			
		||||
							
								
								
									
										57
									
								
								include/boost/utility/typed_in_place_factory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								include/boost/utility/typed_in_place_factory.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
// 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_TYPED_INPLACE_FACTORY_25AGO2003_HPP
 | 
			
		||||
#define BOOST_UTILITY_TYPED_INPLACE_FACTORY_25AGO2003_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/utility/detail/in_place_factory_prefix.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
class typed_in_place_factory_base {} ;
 | 
			
		||||
 | 
			
		||||
#define BOOST_DEFINE_TYPED_INPLACE_FACTORY_CLASS(z,n,_) \
 | 
			
		||||
template< class T, BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \
 | 
			
		||||
class BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) : public typed_in_place_factory_base \
 | 
			
		||||
{ \
 | 
			
		||||
public: \
 | 
			
		||||
\
 | 
			
		||||
  typedef T value_type ; \
 | 
			
		||||
\
 | 
			
		||||
  BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A,const& a) ) \
 | 
			
		||||
    : \
 | 
			
		||||
    BOOST_PP_ENUM( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _ ) \
 | 
			
		||||
  {} \
 | 
			
		||||
\
 | 
			
		||||
  void apply ( void* address ) const \
 | 
			
		||||
  { \
 | 
			
		||||
    new ( address ) T ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), m_a ) ) ; \
 | 
			
		||||
  } \
 | 
			
		||||
\
 | 
			
		||||
  BOOST_PP_REPEAT( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) \
 | 
			
		||||
} ; \
 | 
			
		||||
\
 | 
			
		||||
template< class T, BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \
 | 
			
		||||
BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) < T , BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \
 | 
			
		||||
in_place ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A, const& a) ) \
 | 
			
		||||
{ \
 | 
			
		||||
  return BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) < T, BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \
 | 
			
		||||
           ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), a ) ) ; \
 | 
			
		||||
} ; \
 | 
			
		||||
 | 
			
		||||
BOOST_PP_REPEAT( BOOST_MAX_INPLACE_FACTORY_ARITY, BOOST_DEFINE_TYPED_INPLACE_FACTORY_CLASS, BOOST_PP_EMPTY() )
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#include <boost/utility/detail/in_place_factory_suffix.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										77
									
								
								include/boost/utility/value_init.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								include/boost/utility/value_init.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
// (C) 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)
 | 
			
		||||
//
 | 
			
		||||
// 21 Ago 2002 (Created) Fernando Cacciola
 | 
			
		||||
//
 | 
			
		||||
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
 | 
			
		||||
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
 | 
			
		||||
 | 
			
		||||
#include "boost/detail/select_type.hpp"
 | 
			
		||||
#include "boost/type_traits/cv_traits.hpp"
 | 
			
		||||
 | 
			
		||||
namespace boost {
 | 
			
		||||
 | 
			
		||||
namespace vinit_detail {
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
class const_T_base
 | 
			
		||||
{
 | 
			
		||||
  protected :
 | 
			
		||||
 | 
			
		||||
   const_T_base() : x() {}
 | 
			
		||||
 | 
			
		||||
   T x ;
 | 
			
		||||
} ;
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct non_const_T_base
 | 
			
		||||
{
 | 
			
		||||
  protected :
 | 
			
		||||
 | 
			
		||||
   non_const_T_base() : x() {}
 | 
			
		||||
 | 
			
		||||
   mutable T x ;
 | 
			
		||||
} ;
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct select_base
 | 
			
		||||
{
 | 
			
		||||
  typedef typename
 | 
			
		||||
    detail::if_true< ::boost::is_const<T>::value >
 | 
			
		||||
      ::template then< const_T_base<T>, non_const_T_base<T> >::type type ;
 | 
			
		||||
} ;
 | 
			
		||||
 | 
			
		||||
} // namespace vinit_detail
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
class value_initialized : private vinit_detail::select_base<T>::type
 | 
			
		||||
{
 | 
			
		||||
  public :
 | 
			
		||||
 | 
			
		||||
    value_initialized() {}
 | 
			
		||||
 | 
			
		||||
    operator T&() const { return this->x ; }
 | 
			
		||||
 | 
			
		||||
    T& data() const { return this->x ; }
 | 
			
		||||
 | 
			
		||||
} ;
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
T const& get ( value_initialized<T> const& x )
 | 
			
		||||
{
 | 
			
		||||
  return x.data() ;
 | 
			
		||||
}
 | 
			
		||||
template<class T>
 | 
			
		||||
T& get ( value_initialized<T>& x )
 | 
			
		||||
{
 | 
			
		||||
  return x.data() ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
<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="enable_if.html">enable_if</a><br>
 | 
			
		||||
                <a href="iterator_adaptors.htm">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>Revised 
 | 
			
		||||
			<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->01 September, 2003<!--webbot bot="Timestamp" endspan i-checksum="38582" --></p>
 | 
			
		||||
		<p> </p>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,443 +0,0 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
 | 
			
		||||
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <meta name="generator" content="HTML Tidy, see www.w3.org">
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 | 
			
		||||
    <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
    <meta name="ProgId" content="FrontPage.Editor.Document">
 | 
			
		||||
 | 
			
		||||
    <title>Indirect Iterator Adaptor Documentation</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
	
 | 
			
		||||
    <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
 | 
			
		||||
    "center" width="277" height="86"> 
 | 
			
		||||
 | 
			
		||||
    <h1>Indirect Iterator Adaptor</h1>
 | 
			
		||||
    Defined in header <a href=
 | 
			
		||||
    "../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a> 
 | 
			
		||||
 | 
			
		||||
    <p>The indirect iterator adaptor augments an iterator by applying an
 | 
			
		||||
    <b>extra</b> dereference inside of <tt>operator*()</tt>. For example, this
 | 
			
		||||
    iterator makes it possible to view a container of pointers or
 | 
			
		||||
    smart-pointers (e.g. <tt>std::list<boost::shared_ptr<foo>
 | 
			
		||||
    ></tt>) as if it were a container of the pointed-to type. The following
 | 
			
		||||
    <b>pseudo-code</b> shows the basic idea of the indirect iterator:
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
// inside a hypothetical indirect_iterator class...
 | 
			
		||||
typedef std::iterator_traits<BaseIterator>::value_type Pointer;
 | 
			
		||||
typedef std::iterator_traits<Pointer>::reference reference;
 | 
			
		||||
 | 
			
		||||
reference indirect_iterator::operator*() const {
 | 
			
		||||
  return **this->base_iterator;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h2>Synopsis</h2>
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template <class BaseIterator,
 | 
			
		||||
            class Value, class Reference, class Category, class Pointer>
 | 
			
		||||
  struct indirect_iterator_generator;
 | 
			
		||||
  
 | 
			
		||||
  template <class BaseIterator,
 | 
			
		||||
            class Value, class Reference, class ConstReference, 
 | 
			
		||||
            class Category, class Pointer, class ConstPointer>
 | 
			
		||||
  struct indirect_iterator_pair_generator;
 | 
			
		||||
 | 
			
		||||
  template <class BaseIterator>
 | 
			
		||||
  typename indirect_iterator_generator<BaseIterator>::type
 | 
			
		||||
  make_indirect_iterator(BaseIterator base)  
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="indirect_iterator_generator">The Indirect Iterator Type
 | 
			
		||||
    Generator</a></h2>
 | 
			
		||||
    The <tt>indirect_iterator_generator</tt> template is a <a href=
 | 
			
		||||
    "../../more/generic_programming.html#type_generator">generator</a> of
 | 
			
		||||
    indirect iterator types. The main template parameter for this class is the
 | 
			
		||||
    <tt>BaseIterator</tt> type that is being wrapped. In most cases the type of
 | 
			
		||||
    the elements being pointed to can be deduced using
 | 
			
		||||
    <tt>std::iterator_traits</tt>, but in some situations the user may want to
 | 
			
		||||
    override this type, so there are also template parameters that allow a user
 | 
			
		||||
    to control the <tt>value_type</tt>, <tt>pointer</tt>, and
 | 
			
		||||
    <tt>reference</tt> types of the resulting iterators. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class BaseIterator,
 | 
			
		||||
          class Value, class Reference, class Pointer>
 | 
			
		||||
class indirect_iterator_generator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  typedef <tt><a href=
 | 
			
		||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting indirect iterator type 
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Example</h3>
 | 
			
		||||
    This example uses the <tt>indirect_iterator_generator</tt> to create
 | 
			
		||||
    indirect iterators which dereference the pointers stored in the
 | 
			
		||||
    <tt>pointers_to_chars</tt> array to access the <tt>char</tt>s in the
 | 
			
		||||
    <tt>characters</tt> array. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  char characters[] = "abcdefg";
 | 
			
		||||
  const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
 | 
			
		||||
  char* pointers_to_chars[N];                        // at the end.
 | 
			
		||||
  for (int i = 0; i < N; ++i)
 | 
			
		||||
    pointers_to_chars[i] = &characters[i];
 | 
			
		||||
  
 | 
			
		||||
  boost::indirect_iterator_generator<char**, char>::type 
 | 
			
		||||
    indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
 | 
			
		||||
 | 
			
		||||
  std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  
 | 
			
		||||
  // to be continued...
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
    <table border>
 | 
			
		||||
      <tr>
 | 
			
		||||
        <th>Parameter
 | 
			
		||||
 | 
			
		||||
        <th>Description
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>BaseIterator</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The iterator type being wrapped. The <tt>value_type</tt>
 | 
			
		||||
        of the base iterator should itself be dereferenceable.  
 | 
			
		||||
        The return type of the <tt>operator*</tt> for the
 | 
			
		||||
        <tt>value_type</tt> should match the <tt>Reference</tt> type.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Value</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>value_type</tt> of the resulting iterator, unless const. If
 | 
			
		||||
        Value is <tt>const X</tt>, a conforming compiler makes the
 | 
			
		||||
        <tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
 | 
			
		||||
        "iterator_adaptors.htm#1">[1]</a>. Note that if the default
 | 
			
		||||
         is used for <tt>Value</tt>, then there must be a valid specialization
 | 
			
		||||
         of <tt>iterator_traits</tt> for the value type of the base iterator.
 | 
			
		||||
         <br>
 | 
			
		||||
         <b>Default:</b> <tt>std::iterator_traits<<br>
 | 
			
		||||
         <20> std::iterator_traits<BaseIterator>::value_type
 | 
			
		||||
        >::value_type</tt><a href="#2">[2]</a> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Reference</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>reference</tt> type of the resulting iterator, and in
 | 
			
		||||
        particular, the result type of <tt>operator*()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> <tt>Value&</tt> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Pointer</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>pointer</tt> type of the resulting iterator, and in
 | 
			
		||||
        particular, the result type of <tt>operator->()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> <tt>Value*</tt> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Category</tt> 
 | 
			
		||||
        <td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
 | 
			
		||||
         <b>Default:</b>
 | 
			
		||||
        <tt>std::iterator_traits<BaseIterator>::iterator_category</tt> 
 | 
			
		||||
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3>Concept Model</h3>
 | 
			
		||||
    The indirect iterator will model whichever <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/Iterators.html">standard iterator
 | 
			
		||||
    concept category</a> is modeled by the base iterator. Thus, if the
 | 
			
		||||
    base iterator is a model of <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
    Access Iterator</a> then so is the resulting indirect iterator. If
 | 
			
		||||
    the base iterator models a more restrictive concept, the resulting
 | 
			
		||||
    indirect iterator will model the same concept <a href="#3">[3]</a>.
 | 
			
		||||
 | 
			
		||||
    <h3>Members</h3>
 | 
			
		||||
    The indirect iterator type implements the member functions and operators
 | 
			
		||||
    required of the <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
 | 
			
		||||
    Iterator</a> concept. In addition it has the following constructor: 
 | 
			
		||||
<pre>
 | 
			
		||||
explicit indirect_iterator_generator::type(const BaseIterator& it)
 | 
			
		||||
</pre>
 | 
			
		||||
    <br>
 | 
			
		||||
     <br>
 | 
			
		||||
     
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="indirect_iterator_pair_generator">The Indirect Iterator Pair
 | 
			
		||||
    Generator</a></h2>
 | 
			
		||||
    Sometimes a pair of <tt>const</tt>/non-<tt>const</tt> pair of iterators is
 | 
			
		||||
    needed, such as when implementing a container. The
 | 
			
		||||
    <tt>indirect_iterator_pair_generator</tt> class makes it more convenient to
 | 
			
		||||
    create this pair of iterator types. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class BaseIterator,
 | 
			
		||||
          class Value, class Pointer, class Reference,
 | 
			
		||||
          class ConstPointer, class ConstReference>
 | 
			
		||||
class indirect_iterator_pair_generator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  typedef <tt><a href=
 | 
			
		||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> iterator;       // the mutable indirect iterator type 
 | 
			
		||||
  typedef <tt><a href=
 | 
			
		||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> const_iterator; // the immutable indirect iterator type 
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
  // continuing from the last example...
 | 
			
		||||
 | 
			
		||||
  typedef boost::indirect_iterator_pair_generator<char**,
 | 
			
		||||
    char, char*, char&, const char*, const char&> PairGen;
 | 
			
		||||
 | 
			
		||||
  char mutable_characters[N];
 | 
			
		||||
  char* pointers_to_mutable_chars[N];
 | 
			
		||||
  for (int i = 0; i < N; ++i)
 | 
			
		||||
    pointers_to_mutable_chars[i] = &mutable_characters[i];
 | 
			
		||||
 | 
			
		||||
  PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
 | 
			
		||||
    mutable_indirect_last(pointers_to_mutable_chars + N);
 | 
			
		||||
  PairGen::const_iterator const_indirect_first(pointers_to_chars),
 | 
			
		||||
    const_indirect_last(pointers_to_chars + N);
 | 
			
		||||
 | 
			
		||||
  std::transform(const_indirect_first, const_indirect_last,
 | 
			
		||||
     mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
 | 
			
		||||
 | 
			
		||||
  std::copy(mutable_indirect_first, mutable_indirect_last,
 | 
			
		||||
      std::ostream_iterator<char>(std::cout, ","));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  // to be continued...
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <p>The output is:
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
b,c,d,e,f,g,h,
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
    <table border>
 | 
			
		||||
      <tr>
 | 
			
		||||
        <th>Parameter
 | 
			
		||||
 | 
			
		||||
        <th>Description
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>BaseIterator</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The iterator type being wrapped. The <tt>value_type</tt> of the
 | 
			
		||||
        base iterator should itself be dereferenceable.
 | 
			
		||||
        The return type of the <tt>operator*</tt> for the
 | 
			
		||||
        <tt>value_type</tt> should match the <tt>Reference</tt> type.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Value</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>value_type</tt> of the resulting iterators.
 | 
			
		||||
         If Value is <tt>const X</tt>, a conforming compiler makes the
 | 
			
		||||
         <tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
 | 
			
		||||
         "iterator_adaptors.htm#1">[1]</a>. Note that if the default
 | 
			
		||||
         is used for <tt>Value</tt>, then there must be a valid
 | 
			
		||||
         specialization of <tt>iterator_traits</tt> for the value type
 | 
			
		||||
         of the base iterator.<br>
 | 
			
		||||
 | 
			
		||||
         <b>Default:</b> <tt>std::iterator_traits<<br>
 | 
			
		||||
         <20> std::iterator_traits<BaseIterator>::value_type
 | 
			
		||||
        >::value_type</tt><a href="#2">[2]</a> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Reference</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>reference</tt> type of the resulting <tt>iterator</tt>, and
 | 
			
		||||
        in particular, the result type of its <tt>operator*()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> <tt>Value&</tt> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Pointer</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>pointer</tt> type of the resulting <tt>iterator</tt>, and
 | 
			
		||||
        in particular, the result type of its <tt>operator->()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> <tt>Value*</tt> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>ConstReference</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>reference</tt> type of the resulting
 | 
			
		||||
        <tt>const_iterator</tt>, and in particular, the result type of its
 | 
			
		||||
        <tt>operator*()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> <tt>const Value&</tt> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>ConstPointer</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>pointer</tt> type of the resulting <tt>const_iterator</tt>,
 | 
			
		||||
        and in particular, the result type of its <tt>operator->()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> <tt>const Value*</tt> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Category</tt> 
 | 
			
		||||
        <td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
 | 
			
		||||
         <b>Default:</b>
 | 
			
		||||
        <tt>std::iterator_traits<BaseIterator>::iterator_category</tt> 
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3>Concept Model</h3>
 | 
			
		||||
 | 
			
		||||
    The indirect iterators will model whichever <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/Iterators.html">standard iterator
 | 
			
		||||
    concept category</a> is modeled by the base iterator. Thus, if the
 | 
			
		||||
    base iterator is a model of <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
    Access Iterator</a> then so are the resulting indirect
 | 
			
		||||
    iterators. If the base iterator models a more restrictive concept,
 | 
			
		||||
    the resulting indirect iterators will model the same concept <a
 | 
			
		||||
    href="#3">[3]</a>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <h3>Members</h3>
 | 
			
		||||
    The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types implement
 | 
			
		||||
    the member functions and operators required of the <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
 | 
			
		||||
    Iterator</a> concept. In addition they support the following constructors: 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
explicit indirect_iterator_pair_generator::iterator(const BaseIterator& it)
 | 
			
		||||
explicit indirect_iterator_pair_generator::const_iterator(const BaseIterator& it)
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <br>
 | 
			
		||||
     <br>
 | 
			
		||||
     
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="make_indirect_iterator">The Indirect Iterator Object
 | 
			
		||||
    Generator</a></h2>
 | 
			
		||||
    The <tt>make_indirect_iterator()</tt> function provides a more convenient
 | 
			
		||||
    way to create indirect iterator objects. The function saves the user the
 | 
			
		||||
    trouble of explicitly writing out the iterator types. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class BaseIterator>
 | 
			
		||||
typename indirect_iterator_generator<BaseIterator>::type
 | 
			
		||||
make_indirect_iterator(BaseIterator base)  
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Example</h3>
 | 
			
		||||
    Here we again print the <tt>char</tt>s from the array <tt>characters</tt>
 | 
			
		||||
    by accessing them through the array of pointers <tt>pointer_to_chars</tt>,
 | 
			
		||||
    but this time we use the <tt>make_indirect_iterator()</tt> function which
 | 
			
		||||
    saves us some typing. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
  // continuing from the last example...
 | 
			
		||||
 | 
			
		||||
  std::copy(boost::make_indirect_iterator(pointers_to_chars), 
 | 
			
		||||
      boost::make_indirect_iterator(pointers_to_chars + N),
 | 
			
		||||
      std::ostream_iterator<char>(std::cout, ","));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    The output is: 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
a,b,c,d,e,f,g,
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <h3>Notes</h3>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
 | 
			
		||||
    <p><a name="2">[2]</a> If your compiler does not support partial
 | 
			
		||||
    specialization and the base iterator or its <tt>value_type</tt> is a
 | 
			
		||||
    builtin pointer type, you will not be able to use the default for
 | 
			
		||||
    <tt>Value</tt> and will need to specify this type explicitly.
 | 
			
		||||
 | 
			
		||||
    <p><a name="3">[3]</a>There is a caveat to which concept the
 | 
			
		||||
    indirect iterator can model.  If the return type of the
 | 
			
		||||
    <tt>operator*</tt> for the base iterator's value type is not a
 | 
			
		||||
    true reference, then strickly speaking, the indirect iterator can
 | 
			
		||||
    not be a model of <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward
 | 
			
		||||
    Iterator</a> or any of the concepts that refine it. In this case
 | 
			
		||||
    the <tt>Category</tt> for the indirect iterator should be
 | 
			
		||||
    specified as <tt>std::input_iterator_tag</tt>. However, even in
 | 
			
		||||
    this case, if the base iterator is a random access iterator, the
 | 
			
		||||
    resulting indirect iterator will still satisfy most of the
 | 
			
		||||
    requirements for <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
    Access Iterator</a>.
 | 
			
		||||
    
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <p>Revised 
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->08 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14892" -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <p>© Copyright Jeremy Siek and David Abrahams 2001. Permission to
 | 
			
		||||
    copy, use, modify, sell and distribute this document is granted provided
 | 
			
		||||
    this copyright notice appears in all copies. This document is provided "as
 | 
			
		||||
    is" without express or implied warranty, and with no claim as to its
 | 
			
		||||
    suitability for any purpose. 
 | 
			
		||||
    <!--  LocalWords:  html charset alt gif hpp BaseIterator const namespace struct
 | 
			
		||||
             -->
 | 
			
		||||
     
 | 
			
		||||
    <!--  LocalWords:  ConstPointer ConstReference typename iostream int abcdefg
 | 
			
		||||
             -->
 | 
			
		||||
     <!--  LocalWords:  sizeof  PairGen pre Jeremy Siek David Abrahams
 | 
			
		||||
             -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
 | 
			
		||||
// distribute this software is granted provided this copyright notice appears
 | 
			
		||||
// in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
// warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  char characters[] = "abcdefg";
 | 
			
		||||
  const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
 | 
			
		||||
  char* pointers_to_chars[N];                        // at the end.
 | 
			
		||||
  for (int i = 0; i < N; ++i)
 | 
			
		||||
    pointers_to_chars[i] = &characters[i];
 | 
			
		||||
 | 
			
		||||
  // Example of using indirect_iterator_generator
 | 
			
		||||
  
 | 
			
		||||
  boost::indirect_iterator_generator<char**, char>::type 
 | 
			
		||||
    indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
 | 
			
		||||
 | 
			
		||||
  std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Example of using indirect_iterator_pair_generator
 | 
			
		||||
 | 
			
		||||
  typedef boost::indirect_iterator_pair_generator<char**, char> PairGen;
 | 
			
		||||
 | 
			
		||||
  char mutable_characters[N];
 | 
			
		||||
  char* pointers_to_mutable_chars[N];
 | 
			
		||||
  for (int i = 0; i < N; ++i)
 | 
			
		||||
    pointers_to_mutable_chars[i] = &mutable_characters[i];
 | 
			
		||||
 | 
			
		||||
  PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
 | 
			
		||||
    mutable_indirect_last(pointers_to_mutable_chars + N);
 | 
			
		||||
  PairGen::const_iterator const_indirect_first(pointers_to_chars),
 | 
			
		||||
    const_indirect_last(pointers_to_chars + N);
 | 
			
		||||
 | 
			
		||||
  std::transform(const_indirect_first, const_indirect_last,
 | 
			
		||||
		 mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
 | 
			
		||||
 | 
			
		||||
  std::copy(mutable_indirect_first, mutable_indirect_last,
 | 
			
		||||
	    std::ostream_iterator<char>(std::cout, ","));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  // Example of using make_indirect_iterator()
 | 
			
		||||
 | 
			
		||||
  std::copy(boost::make_indirect_iterator(pointers_to_chars), 
 | 
			
		||||
	    boost::make_indirect_iterator(pointers_to_chars + N),
 | 
			
		||||
	    std::ostream_iterator<char>(std::cout, ","));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,151 +0,0 @@
 | 
			
		||||
//  (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  08 Mar 2001   Jeremy Siek
 | 
			
		||||
//       Moved test of indirect iterator into its own file. It to
 | 
			
		||||
//       to be in iterator_adaptor_test.cpp.
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
#include <boost/pending/iterator_tests.hpp>
 | 
			
		||||
#include <boost/concept_archetype.hpp>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <deque>
 | 
			
		||||
#include <set>
 | 
			
		||||
 | 
			
		||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
 | 
			
		||||
 | 
			
		||||
using boost::dummyT;
 | 
			
		||||
 | 
			
		||||
typedef std::deque<int> storage;
 | 
			
		||||
typedef std::deque<int*> pointer_deque;
 | 
			
		||||
typedef std::set<storage::iterator> iterator_set;
 | 
			
		||||
 | 
			
		||||
void more_indirect_iterator_tests()
 | 
			
		||||
{
 | 
			
		||||
// For some reason all heck breaks loose in the compiler under these conditions.
 | 
			
		||||
#if !defined(BOOST_MSVC) || !defined(__STL_DEBUG)
 | 
			
		||||
    storage store(1000);
 | 
			
		||||
    std::generate(store.begin(), store.end(), rand);
 | 
			
		||||
    
 | 
			
		||||
    pointer_deque ptr_deque;
 | 
			
		||||
    iterator_set iter_set;
 | 
			
		||||
 | 
			
		||||
    for (storage::iterator p = store.begin(); p != store.end(); ++p)
 | 
			
		||||
    {
 | 
			
		||||
        ptr_deque.push_back(&*p);
 | 
			
		||||
        iter_set.insert(p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    typedef boost::indirect_iterator_pair_generator<
 | 
			
		||||
        pointer_deque::iterator
 | 
			
		||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
        , int
 | 
			
		||||
#endif
 | 
			
		||||
    > IndirectDeque;
 | 
			
		||||
 | 
			
		||||
    IndirectDeque::iterator db(ptr_deque.begin());
 | 
			
		||||
    IndirectDeque::iterator de(ptr_deque.end());
 | 
			
		||||
    assert(static_cast<std::size_t>(de - db) == store.size());
 | 
			
		||||
    assert(db + store.size() == de);
 | 
			
		||||
    IndirectDeque::const_iterator dci(db);
 | 
			
		||||
    assert(db == dci);
 | 
			
		||||
    assert(dci == db);
 | 
			
		||||
    assert(dci != de);
 | 
			
		||||
    assert(dci < de);
 | 
			
		||||
    assert(dci <= de);
 | 
			
		||||
    assert(de >= dci);
 | 
			
		||||
    assert(de > dci);
 | 
			
		||||
    dci = de;
 | 
			
		||||
    assert(dci == de);
 | 
			
		||||
 | 
			
		||||
    boost::random_access_iterator_test(db + 1, store.size() - 1, boost::next(store.begin()));
 | 
			
		||||
    
 | 
			
		||||
    *db = 999;
 | 
			
		||||
    assert(store.front() == 999);
 | 
			
		||||
 | 
			
		||||
    // Borland C++ is getting very confused about the typedef's here
 | 
			
		||||
 | 
			
		||||
    typedef boost::indirect_iterator_generator<
 | 
			
		||||
        iterator_set::iterator
 | 
			
		||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
        , int
 | 
			
		||||
#endif
 | 
			
		||||
        >::type indirect_set_iterator;
 | 
			
		||||
 | 
			
		||||
    typedef boost::indirect_iterator_generator<
 | 
			
		||||
        iterator_set::iterator,
 | 
			
		||||
        const int
 | 
			
		||||
        >::type const_indirect_set_iterator;
 | 
			
		||||
 | 
			
		||||
    indirect_set_iterator sb(iter_set.begin());
 | 
			
		||||
    indirect_set_iterator se(iter_set.end());
 | 
			
		||||
    const_indirect_set_iterator sci(iter_set.begin());
 | 
			
		||||
    assert(sci == sb);
 | 
			
		||||
    assert(sci != se);
 | 
			
		||||
    sci = se;
 | 
			
		||||
    assert(sci == se);
 | 
			
		||||
    
 | 
			
		||||
    *boost::prior(se) = 888;
 | 
			
		||||
    assert(store.back() == 888);
 | 
			
		||||
    assert(std::equal(sb, se, store.begin()));
 | 
			
		||||
 | 
			
		||||
    boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]);
 | 
			
		||||
    assert(std::equal(db, de, store.begin()));
 | 
			
		||||
 | 
			
		||||
#endif    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main()
 | 
			
		||||
{
 | 
			
		||||
  dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
 | 
			
		||||
                     dummyT(3), dummyT(4), dummyT(5) };
 | 
			
		||||
  const int N = sizeof(array)/sizeof(dummyT);
 | 
			
		||||
 | 
			
		||||
  // Test indirect_iterator_generator
 | 
			
		||||
  {
 | 
			
		||||
    dummyT* ptr[N];
 | 
			
		||||
    for (int k = 0; k < N; ++k)
 | 
			
		||||
      ptr[k] = array + k;
 | 
			
		||||
 | 
			
		||||
    typedef boost::indirect_iterator_generator<dummyT**
 | 
			
		||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
        , dummyT
 | 
			
		||||
#endif
 | 
			
		||||
      >::type indirect_iterator;
 | 
			
		||||
 | 
			
		||||
    typedef boost::indirect_iterator_generator<dummyT**, const dummyT>::type const_indirect_iterator;
 | 
			
		||||
 | 
			
		||||
    indirect_iterator i(ptr);
 | 
			
		||||
    boost::random_access_iterator_test(i, N, array);
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
 | 
			
		||||
#endif
 | 
			
		||||
    
 | 
			
		||||
    // check operator->
 | 
			
		||||
    assert((*i).m_x == i->foo());
 | 
			
		||||
 | 
			
		||||
    const_indirect_iterator j(ptr);
 | 
			
		||||
    boost::random_access_iterator_test(j, N, array);
 | 
			
		||||
 | 
			
		||||
    dummyT*const* const_ptr = ptr;
 | 
			
		||||
    
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
 | 
			
		||||
#endif
 | 
			
		||||
    boost::const_nonconst_iterator_test(i, ++j);
 | 
			
		||||
 | 
			
		||||
    more_indirect_iterator_tests();
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << "test successful " << std::endl;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
//  Test boost/pending/iterator_adaptors.hpp
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
// Revision History
 | 
			
		||||
// 21 Jan 01 Initial version (Jeremy Siek)
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <boost/pending/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  typedef boost::iterator_adaptor<std::list<int>::iterator,
 | 
			
		||||
    boost::default_iterator_policies,
 | 
			
		||||
    int,int&,int*,std::bidirectional_iterator_tag> adaptor_type;
 | 
			
		||||
  
 | 
			
		||||
  adaptor_type i;
 | 
			
		||||
  i += 4;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
//  Test boost/pending/iterator_adaptors.hpp
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
// Revision History
 | 
			
		||||
// 21 Jan 01 Initial version (Jeremy Siek)
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <boost/pending/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  typedef boost::iterator_adaptor<std::istream_iterator<int>,
 | 
			
		||||
    boost::default_iterator_policies,
 | 
			
		||||
    int,int&,int*,std::input_iterator_tag> adaptor_type;
 | 
			
		||||
  
 | 
			
		||||
  adaptor_type iter;
 | 
			
		||||
  --iter;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,61 +0,0 @@
 | 
			
		||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
 | 
			
		||||
// sell and distribute this software is granted provided this
 | 
			
		||||
// copyright notice appears in all copies. This software is provided
 | 
			
		||||
// "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
// to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
// 8 Mar 2001   Jeremy Siek
 | 
			
		||||
//     Initial checkin.
 | 
			
		||||
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
#include <boost/pending/iterator_tests.hpp>
 | 
			
		||||
#include <boost/static_assert.hpp>
 | 
			
		||||
 | 
			
		||||
class bar { };
 | 
			
		||||
void foo(bar) { }
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main()
 | 
			
		||||
{
 | 
			
		||||
  using boost::dummyT;
 | 
			
		||||
  dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
 | 
			
		||||
		     dummyT(3), dummyT(4), dummyT(5) };
 | 
			
		||||
  typedef boost::iterator_adaptor<dummyT*, 
 | 
			
		||||
    boost::default_iterator_policies, dummyT> my_iter;
 | 
			
		||||
  my_iter mi(array);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    typedef boost::iterator_adaptor<my_iter, boost::default_iterator_policies,
 | 
			
		||||
      boost::iterator_traits_generator
 | 
			
		||||
      ::reference<dummyT>
 | 
			
		||||
      ::iterator_category<std::input_iterator_tag> > iter_type;
 | 
			
		||||
 | 
			
		||||
    BOOST_STATIC_ASSERT((boost::is_same<iter_type::iterator_category*,
 | 
			
		||||
       std::input_iterator_tag*>::value));
 | 
			
		||||
 | 
			
		||||
    BOOST_STATIC_ASSERT(( ! boost::is_convertible<iter_type::iterator_category*,
 | 
			
		||||
       std::forward_iterator_tag*>::value));
 | 
			
		||||
 | 
			
		||||
    iter_type i(mi);
 | 
			
		||||
    boost::input_iterator_test(i, dummyT(0), dummyT(1));
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    typedef boost::iterator_adaptor<dummyT*,
 | 
			
		||||
      boost::default_iterator_policies,
 | 
			
		||||
      boost::iterator_traits_generator
 | 
			
		||||
        ::value_type<dummyT>
 | 
			
		||||
        ::reference<const dummyT&>
 | 
			
		||||
        ::pointer<const dummyT*> 
 | 
			
		||||
        ::iterator_category<std::forward_iterator_tag>
 | 
			
		||||
        ::difference_type<std::ptrdiff_t> > adaptor_type;
 | 
			
		||||
 | 
			
		||||
    adaptor_type i(array);
 | 
			
		||||
 | 
			
		||||
    boost::input_iterator_test(i, dummyT(0), dummyT(1));
 | 
			
		||||
    int zero = 0;
 | 
			
		||||
    if (zero) // don't do this, just make sure it compiles
 | 
			
		||||
      assert((*i).m_x == i->foo());      
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
 | 
			
		||||
// distribute this software is granted provided this copyright notice appears
 | 
			
		||||
// in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
// warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <boost/pending/iterator_adaptors.hpp>
 | 
			
		||||
#include <boost/pending/integer_range.hpp>
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  // This is a simple example of using the transform_iterators class to
 | 
			
		||||
  // generate iterators that multiply the value returned by dereferencing
 | 
			
		||||
  // the iterator. In this case we are multiplying by 2.
 | 
			
		||||
  // Would be cooler to use lambda library in this example.
 | 
			
		||||
 | 
			
		||||
  int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
 | 
			
		||||
 | 
			
		||||
  typedef std::binder1st< std::multiplies<int> > Function;
 | 
			
		||||
  typedef boost::transform_iterator<Function, int*, 
 | 
			
		||||
    boost::iterator<std::random_access_iterator_tag, int>
 | 
			
		||||
  >::type doubling_iterator;
 | 
			
		||||
 | 
			
		||||
  doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)),
 | 
			
		||||
    i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies<int>(), 2));
 | 
			
		||||
 | 
			
		||||
  std::cout << "multiplying the array by 2:" << std::endl;
 | 
			
		||||
  while (i != i_end)
 | 
			
		||||
    std::cout << *i++ << " ";
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Here is an example of counting from 0 to 5 using the integer_range class.
 | 
			
		||||
 | 
			
		||||
  boost::integer_range<int> r(0,5);
 | 
			
		||||
 | 
			
		||||
  std::cout << "counting to from 0 to 4:" << std::endl;
 | 
			
		||||
  std::copy(r.begin(), r.end(), std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,335 +0,0 @@
 | 
			
		||||
//  Test boost/iterator_adaptors.hpp
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  08 Mar 01 Moved indirect and transform tests to separate files.
 | 
			
		||||
//            (Jeremy Siek)
 | 
			
		||||
//  19 Feb 01 Take adavantage of improved iterator_traits to do more tests
 | 
			
		||||
//            on MSVC. Hack around an MSVC-with-STLport internal compiler
 | 
			
		||||
//            error. (David Abrahams)
 | 
			
		||||
//  11 Feb 01 Added test of operator-> for forward and input iterators.
 | 
			
		||||
//            (Jeremy Siek)
 | 
			
		||||
//  11 Feb 01 Borland fixes (David Abrahams)
 | 
			
		||||
//  10 Feb 01 Use new adaptors interface. (David Abrahams)
 | 
			
		||||
//  10 Feb 01 Use new filter_ interface. (David Abrahams)
 | 
			
		||||
//  09 Feb 01 Use new reverse_ and indirect_ interfaces. Replace
 | 
			
		||||
//            BOOST_NO_STD_ITERATOR_TRAITS with
 | 
			
		||||
//            BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION to prove we've
 | 
			
		||||
//            normalized to core compiler capabilities (David Abrahams)
 | 
			
		||||
//  08 Feb 01 Use Jeremy's new make_reverse_iterator form; add more
 | 
			
		||||
//            comprehensive testing. Force-decay array function arguments to
 | 
			
		||||
//            pointers.
 | 
			
		||||
//  07 Feb 01 Added tests for the make_xxx_iterator() helper functions.
 | 
			
		||||
//            (Jeremy Siek)
 | 
			
		||||
//  07 Feb 01 Replaced use of xxx_pair_generator with xxx_generator where
 | 
			
		||||
//            possible (which was all but the projection iterator).
 | 
			
		||||
//            (Jeremy Siek)
 | 
			
		||||
//  06 Feb 01 Removed now-defaulted template arguments where possible
 | 
			
		||||
//            Updated names to correspond to new generator naming convention.
 | 
			
		||||
//            Added a trivial test for make_transform_iterator().
 | 
			
		||||
//            Gave traits for const iterators a mutable value_type, per std.
 | 
			
		||||
//            Resurrected my original tests for indirect iterators.
 | 
			
		||||
//            (David Abrahams)
 | 
			
		||||
//  04 Feb 01 Fix for compilers without standard iterator_traits
 | 
			
		||||
//            (David Abrahams)
 | 
			
		||||
//  13 Jun 00 Added const version of the iterator tests (Jeremy Siek)
 | 
			
		||||
//  12 Dec 99 Initial version with iterator operators (Jeremy Siek)
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
#include <boost/pending/iterator_tests.hpp>
 | 
			
		||||
#include <boost/pending/integer_range.hpp>
 | 
			
		||||
#include <boost/concept_archetype.hpp>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <deque>
 | 
			
		||||
#include <set>
 | 
			
		||||
 | 
			
		||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
 | 
			
		||||
 | 
			
		||||
using boost::dummyT;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct mult_functor {
 | 
			
		||||
  typedef int result_type;
 | 
			
		||||
  typedef int argument_type;
 | 
			
		||||
  // Functors used with transform_iterator must be
 | 
			
		||||
  // DefaultConstructible, as the transform_iterator must be
 | 
			
		||||
  // DefaultConstructible to satisfy the requirements for
 | 
			
		||||
  // TrivialIterator.
 | 
			
		||||
  mult_functor() { }
 | 
			
		||||
  mult_functor(int aa) : a(aa) { }
 | 
			
		||||
  int operator()(int b) const { return a * b; }
 | 
			
		||||
  int a;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Pair>
 | 
			
		||||
struct select1st_ 
 | 
			
		||||
  : public std::unary_function<Pair, typename Pair::first_type>
 | 
			
		||||
{
 | 
			
		||||
  const typename Pair::first_type& operator()(const Pair& x) const {
 | 
			
		||||
    return x.first;
 | 
			
		||||
  }
 | 
			
		||||
  typename Pair::first_type& operator()(Pair& x) const {
 | 
			
		||||
    return x.first;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct one_or_four {
 | 
			
		||||
  bool operator()(dummyT x) const {
 | 
			
		||||
    return x.foo() == 1 || x.foo() == 4;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef std::deque<int> storage;
 | 
			
		||||
typedef std::deque<int*> pointer_deque;
 | 
			
		||||
typedef std::set<storage::iterator> iterator_set;
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main()
 | 
			
		||||
{
 | 
			
		||||
  dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), 
 | 
			
		||||
                     dummyT(3), dummyT(4), dummyT(5) };
 | 
			
		||||
  const int N = sizeof(array)/sizeof(dummyT);
 | 
			
		||||
 | 
			
		||||
  // sanity check, if this doesn't pass the test is buggy
 | 
			
		||||
  boost::random_access_iterator_test(array,N,array);
 | 
			
		||||
 | 
			
		||||
  // Check that the policy concept checks and the default policy
 | 
			
		||||
  // implementation match up.
 | 
			
		||||
  boost::function_requires< 
 | 
			
		||||
     boost::RandomAccessIteratorPoliciesConcept<
 | 
			
		||||
       boost::default_iterator_policies, int*,
 | 
			
		||||
       boost::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t,
 | 
			
		||||
                      int*, int&>
 | 
			
		||||
      > >();
 | 
			
		||||
 | 
			
		||||
  // Test the iterator_adaptor
 | 
			
		||||
  {
 | 
			
		||||
    boost::iterator_adaptor<dummyT*, boost::default_iterator_policies, dummyT> i(array);
 | 
			
		||||
    boost::random_access_iterator_test(i, N, array);
 | 
			
		||||
    
 | 
			
		||||
    boost::iterator_adaptor<const dummyT*, boost::default_iterator_policies, const dummyT> j(array);
 | 
			
		||||
    boost::random_access_iterator_test(j, N, array);
 | 
			
		||||
    boost::const_nonconst_iterator_test(i, ++j);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Test projection_iterator_pair_generator
 | 
			
		||||
  {    
 | 
			
		||||
    typedef std::pair<dummyT,dummyT> Pair;
 | 
			
		||||
    Pair pair_array[N];
 | 
			
		||||
    for (int k = 0; k < N; ++k)
 | 
			
		||||
      pair_array[k].first = array[k];
 | 
			
		||||
 | 
			
		||||
    typedef boost::projection_iterator_pair_generator<select1st_<Pair>,
 | 
			
		||||
      Pair*, const Pair*
 | 
			
		||||
      > Projection;
 | 
			
		||||
    
 | 
			
		||||
    Projection::iterator i(pair_array);
 | 
			
		||||
    boost::random_access_iterator_test(i, N, array);
 | 
			
		||||
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_projection_iterator(pair_array, select1st_<Pair>()), N, array);    
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_projection_iterator< select1st_<Pair> >(pair_array), N, array);    
 | 
			
		||||
 | 
			
		||||
    Projection::const_iterator j(pair_array);
 | 
			
		||||
    boost::random_access_iterator_test(j, N, array);
 | 
			
		||||
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_const_projection_iterator(pair_array, select1st_<Pair>()), N, array);
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_const_projection_iterator<select1st_<Pair> >(pair_array), N, array);
 | 
			
		||||
 | 
			
		||||
    boost::const_nonconst_iterator_test(i, ++j);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Test reverse_iterator_generator
 | 
			
		||||
  {
 | 
			
		||||
    dummyT reversed[N];
 | 
			
		||||
    std::copy(array, array + N, reversed);
 | 
			
		||||
    std::reverse(reversed, reversed + N);
 | 
			
		||||
    
 | 
			
		||||
    typedef boost::reverse_iterator_generator<dummyT*
 | 
			
		||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
        , dummyT
 | 
			
		||||
#endif
 | 
			
		||||
      >::type reverse_iterator;
 | 
			
		||||
    
 | 
			
		||||
    reverse_iterator i(reversed + N);
 | 
			
		||||
    boost::random_access_iterator_test(i, N, array);
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    typedef boost::reverse_iterator_generator<const dummyT*
 | 
			
		||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
        , const dummyT
 | 
			
		||||
#endif
 | 
			
		||||
      >::type const_reverse_iterator;
 | 
			
		||||
    
 | 
			
		||||
    const_reverse_iterator j(reversed + N);
 | 
			
		||||
    boost::random_access_iterator_test(j, N, array);
 | 
			
		||||
 | 
			
		||||
    const dummyT* const_reversed = reversed;
 | 
			
		||||
    
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
 | 
			
		||||
#endif
 | 
			
		||||
    
 | 
			
		||||
    boost::const_nonconst_iterator_test(i, ++j);    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Test reverse_iterator_generator again, with traits fully deducible on all platforms
 | 
			
		||||
  {
 | 
			
		||||
    std::deque<dummyT> reversed_container;
 | 
			
		||||
    std::reverse_copy(array, array + N, std::back_inserter(reversed_container));
 | 
			
		||||
    const std::deque<dummyT>::iterator reversed = reversed_container.begin();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    typedef boost::reverse_iterator_generator<
 | 
			
		||||
        std::deque<dummyT>::iterator>::type reverse_iterator;
 | 
			
		||||
    typedef boost::reverse_iterator_generator<
 | 
			
		||||
        std::deque<dummyT>::const_iterator, const dummyT>::type const_reverse_iterator;
 | 
			
		||||
 | 
			
		||||
    // MSVC/STLport gives an INTERNAL COMPILER ERROR when any computation
 | 
			
		||||
    // (e.g. "reversed + N") is used in the constructor below.
 | 
			
		||||
    const std::deque<dummyT>::iterator finish = reversed_container.end();
 | 
			
		||||
    reverse_iterator i(finish);
 | 
			
		||||
    
 | 
			
		||||
    boost::random_access_iterator_test(i, N, array);
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);
 | 
			
		||||
 | 
			
		||||
    const_reverse_iterator j = reverse_iterator(finish);
 | 
			
		||||
    boost::random_access_iterator_test(j, N, array);
 | 
			
		||||
 | 
			
		||||
    const std::deque<dummyT>::const_iterator const_reversed = reversed;
 | 
			
		||||
    boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
 | 
			
		||||
    
 | 
			
		||||
    // Many compilers' builtin deque iterators don't interoperate well, though
 | 
			
		||||
    // STLport fixes that problem.
 | 
			
		||||
#if defined(__SGI_STL_PORT) || !defined(__GNUC__) && !defined(__BORLANDC__) && !defined(BOOST_MSVC)
 | 
			
		||||
    boost::const_nonconst_iterator_test(i, ++j);
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Test integer_range's iterators
 | 
			
		||||
  {
 | 
			
		||||
    int int_array[] = { 0, 1, 2, 3, 4, 5 };
 | 
			
		||||
    boost::integer_range<int> r(0, 5);
 | 
			
		||||
    boost::random_access_iterator_test(r.begin(), r.size(), int_array);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Test filter iterator
 | 
			
		||||
  {
 | 
			
		||||
    // Using typedefs for filter_gen::type confused Borland terribly.
 | 
			
		||||
    typedef boost::detail::non_bidirectional_category<dummyT*>::type category;
 | 
			
		||||
    
 | 
			
		||||
    typedef boost::filter_iterator_generator<one_or_four, dummyT*
 | 
			
		||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
        , dummyT
 | 
			
		||||
#endif
 | 
			
		||||
        >::type filter_iter;
 | 
			
		||||
 | 
			
		||||
#if defined(__BORLANDC__)
 | 
			
		||||
    // Borland is choking on accessing the policies_type explicitly
 | 
			
		||||
    // from the filter_iter. 
 | 
			
		||||
    boost::forward_iterator_test(make_filter_iterator(array, array+N, 
 | 
			
		||||
						      one_or_four()),
 | 
			
		||||
				 dummyT(1), dummyT(4));
 | 
			
		||||
#else
 | 
			
		||||
    filter_iter i(array, filter_iter::policies_type(one_or_four(), array + N));
 | 
			
		||||
    boost::forward_iterator_test(i, dummyT(1), dummyT(4));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(__BORLANDC__)
 | 
			
		||||
    // 
 | 
			
		||||
    enum { is_forward = boost::is_same<
 | 
			
		||||
           filter_iter::iterator_category,
 | 
			
		||||
           std::forward_iterator_tag>::value };
 | 
			
		||||
    BOOST_STATIC_ASSERT(is_forward);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // On compilers not supporting partial specialization, we can do more type
 | 
			
		||||
    // deduction with deque iterators than with pointers... unless the library
 | 
			
		||||
    // is broken ;-(
 | 
			
		||||
#if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT)
 | 
			
		||||
    std::deque<dummyT> array2;
 | 
			
		||||
    std::copy(array+0, array+N, std::back_inserter(array2));
 | 
			
		||||
    boost::forward_iterator_test(
 | 
			
		||||
        boost::make_filter_iterator(array2.begin(), array2.end(), one_or_four()),
 | 
			
		||||
        dummyT(1), dummyT(4));
 | 
			
		||||
 | 
			
		||||
    boost::forward_iterator_test(
 | 
			
		||||
        boost::make_filter_iterator<one_or_four>(array2.begin(), array2.end()),
 | 
			
		||||
        dummyT(1), dummyT(4));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_MSVC) // This just freaks MSVC out completely
 | 
			
		||||
    boost::forward_iterator_test(
 | 
			
		||||
        boost::make_filter_iterator<one_or_four>(
 | 
			
		||||
            boost::make_reverse_iterator(array2.end()),
 | 
			
		||||
            boost::make_reverse_iterator(array2.begin())
 | 
			
		||||
            ),
 | 
			
		||||
        dummyT(4), dummyT(1));
 | 
			
		||||
#endif
 | 
			
		||||
    
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
    boost::forward_iterator_test(
 | 
			
		||||
        boost::make_filter_iterator(array+0, array+N, one_or_four()),
 | 
			
		||||
        dummyT(1), dummyT(4));
 | 
			
		||||
 | 
			
		||||
    boost::forward_iterator_test(
 | 
			
		||||
        boost::make_filter_iterator<one_or_four>(array, array + N),
 | 
			
		||||
        dummyT(1), dummyT(4));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // check operator-> with a forward iterator
 | 
			
		||||
  {
 | 
			
		||||
    boost::forward_iterator_archetype<dummyT> forward_iter;
 | 
			
		||||
#if defined(__BORLANDC__)
 | 
			
		||||
    typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>,
 | 
			
		||||
      boost::default_iterator_policies,
 | 
			
		||||
      dummyT, const dummyT&, const dummyT*, 
 | 
			
		||||
      std::forward_iterator_tag, std::ptrdiff_t> adaptor_type;
 | 
			
		||||
#else
 | 
			
		||||
    typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>,
 | 
			
		||||
      boost::default_iterator_policies,
 | 
			
		||||
      boost::iterator_traits_generator
 | 
			
		||||
        ::value_type<dummyT>
 | 
			
		||||
        ::reference<const dummyT&>
 | 
			
		||||
        ::pointer<const dummyT*> 
 | 
			
		||||
        ::iterator_category<std::forward_iterator_tag>
 | 
			
		||||
        ::difference_type<std::ptrdiff_t> > adaptor_type;
 | 
			
		||||
#endif
 | 
			
		||||
    adaptor_type i(forward_iter);
 | 
			
		||||
    int zero = 0;
 | 
			
		||||
    if (zero) // don't do this, just make sure it compiles
 | 
			
		||||
      assert((*i).m_x == i->foo());      
 | 
			
		||||
  }
 | 
			
		||||
  // check operator-> with an input iterator
 | 
			
		||||
  {
 | 
			
		||||
    boost::input_iterator_archetype<dummyT> input_iter;
 | 
			
		||||
    typedef boost::iterator_adaptor<boost::input_iterator_archetype<dummyT>,
 | 
			
		||||
      boost::default_iterator_policies,
 | 
			
		||||
      dummyT, const dummyT&, const dummyT*, 
 | 
			
		||||
      std::input_iterator_tag, std::ptrdiff_t> adaptor_type;
 | 
			
		||||
    adaptor_type i(input_iter);
 | 
			
		||||
    int zero = 0;
 | 
			
		||||
    if (zero) // don't do this, just make sure it compiles
 | 
			
		||||
      assert((*i).m_x == i->foo());      
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << "test successful " << std::endl;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,891 +1,11 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
 | 
			
		||||
<!-- Copyright David Abrahams 2004. Distributed under the Boost -->
 | 
			
		||||
<!-- Software License, Version 1.0. (See accompanying -->
 | 
			
		||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <meta name="generator" content="HTML Tidy, see www.w3.org">
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 | 
			
		||||
    <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
    <meta name="ProgId" content="FrontPage.Editor.Document">
 | 
			
		||||
 | 
			
		||||
    <title>Boost Iterator Adaptor Library</title>
 | 
			
		||||
<meta http-equiv="refresh" content="0; URL=../iterator/doc/index.html">
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
 | 
			
		||||
    <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
 | 
			
		||||
    "center" width="277" height="86"> 
 | 
			
		||||
 | 
			
		||||
    <h1>Boost Iterator Adaptor Library</h1>
 | 
			
		||||
 | 
			
		||||
    <h2>Introduction</h2>
 | 
			
		||||
 | 
			
		||||
    <p>The Iterator Adaptor library allows you transform an arbitrary ``base''
 | 
			
		||||
    type into a standard-conforming iterator with the behaviors you choose.
 | 
			
		||||
    Doing so is especially easy if the ``base'' type is itself an iterator. The
 | 
			
		||||
    library also supplies several example <a href=
 | 
			
		||||
    "../../more/generic_programming.html#adaptors">adaptors</a> which apply
 | 
			
		||||
    specific useful behaviors to arbitrary base iterators.
 | 
			
		||||
 | 
			
		||||
    <h2>Table of Contents</h2>
 | 
			
		||||
 | 
			
		||||
    <ul>
 | 
			
		||||
      <li>
 | 
			
		||||
        Header <tt><a href=
 | 
			
		||||
        "../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a></tt>
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>
 | 
			
		||||
            Generalized Iterator Adaptor 
 | 
			
		||||
 | 
			
		||||
            <ul>
 | 
			
		||||
              <li>Class template <tt><a href=
 | 
			
		||||
              "#iterator_adaptor">iterator_adaptor</a></tt>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#template_parameters">Template Parameters</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#named_template_parameters">Named Template Parameters</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#policies">The Policies Class</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#additional_members">Additional Class Members</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#example">Example</a>
 | 
			
		||||
 | 
			
		||||
              <li>(<tt>const</tt>/non-<tt>const</tt>) <a href=
 | 
			
		||||
              "#iterator_interactions">Iterator Interactions</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#challenge">Challenge</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#concept_model">Concept Model</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#declaration_synopsis">Declaration Synopsis</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="#notes">Notes</a>
 | 
			
		||||
            </ul>
 | 
			
		||||
 | 
			
		||||
          <li>
 | 
			
		||||
            <a name="specialized_adaptors">Specialized Iterator Adaptors</a> 
 | 
			
		||||
 | 
			
		||||
            <ul>
 | 
			
		||||
              <li><a href="indirect_iterator.htm">Indirect Iterator Adaptor</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="reverse_iterator.htm">Reverse Iterator Adaptor</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="transform_iterator.htm">Transform Iterator
 | 
			
		||||
              Adaptor</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="projection_iterator.htm">Projection Iterator
 | 
			
		||||
              Adaptor</a>
 | 
			
		||||
 | 
			
		||||
              <li><a href="filter_iterator.htm">Filter Iterator Adaptor</a>
 | 
			
		||||
            </ul>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
      <li>Header <tt><a href=
 | 
			
		||||
      "../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a></tt><br>
 | 
			
		||||
 | 
			
		||||
       <a href="counting_iterator.htm">Counting Iterator Adaptor</a>
 | 
			
		||||
 | 
			
		||||
      <li>Header <tt><a href=
 | 
			
		||||
      "../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a></tt><br>
 | 
			
		||||
 | 
			
		||||
       <a href="function_output_iterator.htm">Function Output Iterator Adaptor</a>
 | 
			
		||||
    </ul>
 | 
			
		||||
 | 
			
		||||
    <p><b><a href="file:///c:/boost/site/people/dave_abrahams.htm">Dave
 | 
			
		||||
    Abrahams</a></b> started the library, applying <a href=
 | 
			
		||||
    "../../more/generic_programming.html#policy">policy class</a> technique and
 | 
			
		||||
    handling const/non-const iterator interactions. He also contributed the
 | 
			
		||||
    <tt><a href="indirect_iterator.htm">indirect_</a></tt> and <tt><a href=
 | 
			
		||||
    "reverse_iterator.htm">reverse_</a></tt> iterator generators, and expanded
 | 
			
		||||
    <tt><a href="counting_iterator.htm">counting_iterator_generator</a></tt> to
 | 
			
		||||
    cover all incrementable types. He edited most of the documentation,
 | 
			
		||||
    sometimes heavily.<br>
 | 
			
		||||
     <b><a href="file:///c:/boost/site/people/jeremy_siek.htm">Jeremy
 | 
			
		||||
    Siek</a></b> contributed the <a href="transform_iterator.htm">transform
 | 
			
		||||
    iterator</a> adaptor, the integer-only version of <tt><a href=
 | 
			
		||||
    "counting_iterator.htm">counting_iterator_generator</a></tt>, 
 | 
			
		||||
    the <a href="function_output_iterator.htm">function output iterator</a> 
 | 
			
		||||
    adaptor, and most of the documentation.<br>
 | 
			
		||||
     <b><a href="http://www.boost.org/people/john_potter.htm">John
 | 
			
		||||
    Potter</a></b> contributed the <tt><a href=
 | 
			
		||||
    "projection_iterator.htm">projection_</a></tt> and <tt><a href=
 | 
			
		||||
    "filter_iterator.htm">filter_</a></tt> iterator generators and made some
 | 
			
		||||
    simplifications to the main <tt><a href=
 | 
			
		||||
    "#iterator_adaptor">iterator_adaptor</a></tt> template.<br>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <h2><a name="iterator_adaptor">Class template</a>
 | 
			
		||||
    <tt>iterator_adaptor</tt></h2>
 | 
			
		||||
    Implementing standard conforming iterators is a non-trivial task. There are
 | 
			
		||||
    some fine points such as the interactions between an iterator and its
 | 
			
		||||
    corresponding const_iterator, and there are myriad operators that should be
 | 
			
		||||
    implemented but are easily forgotten or mishandled, such as
 | 
			
		||||
    <tt>operator->()</tt>. Using <tt>iterator_adaptor</tt>, you can easily
 | 
			
		||||
    implement an iterator class, and even more easily extend and <a href=
 | 
			
		||||
    "../../more/generic_programming.html#adaptors">adapt</a> existing iterator
 | 
			
		||||
    types. Moreover, it is easy to make a pair of interoperable <tt>const</tt>
 | 
			
		||||
    and <tt>non-const</tt> iterators. 
 | 
			
		||||
 | 
			
		||||
    <p><tt>iterator_adaptor</tt> is declared like this:
 | 
			
		||||
<pre>
 | 
			
		||||
template <class Base, class Policies, 
 | 
			
		||||
    class ValueOrNamedParams = typename std::iterator_traits<Base>::value_type,
 | 
			
		||||
    class ReferenceOrNamedParams = <i>...(see below)</i>,
 | 
			
		||||
    class PointerOrNamedParams = <i>...(see below)</i>,
 | 
			
		||||
    class CategoryOrNamedParams = typename std::iterator_traits<Base>::iterator_category,
 | 
			
		||||
    class DistanceOrNamedParams = typename std::iterator_traits<Base>::difference_type>
 | 
			
		||||
struct iterator_adaptor;
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
    <h3><a name="template_parameters">Template Parameters</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>Although <tt>iterator_adaptor</tt> takes seven template parameters,
 | 
			
		||||
    defaults have been carefully chosen to minimize the number of parameters
 | 
			
		||||
    you must supply in most cases, especially if <tt>BaseType</tt> is an
 | 
			
		||||
    iterator.
 | 
			
		||||
 | 
			
		||||
    <table border="1" summary="iterator_adaptor template parameters">
 | 
			
		||||
      <tr>
 | 
			
		||||
        <th>Parameter
 | 
			
		||||
 | 
			
		||||
        <th>Description
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>BaseType</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The type being wrapped.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Policies</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>A <a href="../../more/generic_programming.html#policy">policy
 | 
			
		||||
        class</a> that supplies core functionality to the resulting iterator. A
 | 
			
		||||
        detailed description can be found <a href="#policies">below</a>.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Value</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>value_type</tt> of the resulting iterator, unless const. If
 | 
			
		||||
        Value is <tt>const X</tt> the
 | 
			
		||||
        <tt>value_type</tt> will be (<i>non-</i><tt>const</tt>) <tt>X</tt><a href=
 | 
			
		||||
        "#1">[1]</a>. If the <tt>value_type</tt> you wish to use is an abstract
 | 
			
		||||
        base class see note <a href="#5">[5]</a>.<br>
 | 
			
		||||
         <b>Default:</b>
 | 
			
		||||
        <tt>std::iterator_traits<BaseType>::value_type</tt> <a href=
 | 
			
		||||
        "#2">[2]</a>
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Reference</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>reference</tt> type of the resulting iterator, and in
 | 
			
		||||
        particular, the result type of <tt>operator*()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> If <tt>Value</tt> is supplied, <tt>Value&</tt> is
 | 
			
		||||
        used. Otherwise
 | 
			
		||||
        <tt>std::iterator_traits<BaseType>::reference</tt> is used.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Pointer</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>pointer</tt> type of the resulting iterator, and in
 | 
			
		||||
        particular, the result type of <tt>operator->()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
 | 
			
		||||
        otherwise <tt>std::iterator_traits<BaseType>::pointer</tt>.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Category</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
 | 
			
		||||
         <b>Default:</b>
 | 
			
		||||
        <tt>std::iterator_traits<BaseType>::iterator_category</tt> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Distance</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>difference_type</tt> for the resulting iterator.<br>
 | 
			
		||||
         <b>Default:</b>
 | 
			
		||||
        <tt>std::iterator_traits<BaseType>::difference_type</tt> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
         <td><tt>NamedParams</tt>
 | 
			
		||||
 | 
			
		||||
         <td>A list of named template parameters generated using the
 | 
			
		||||
            <a href="#iterator_traits_generator">
 | 
			
		||||
            <tt>iterator_traits_generator</tt></a> class (see below).
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a name="named_template_parameters">Named Template Parameters</a></h3>
 | 
			
		||||
    
 | 
			
		||||
    With seven template parameters, providing arguments for
 | 
			
		||||
    <tt>iterator_adaptor</tt> in the correct order can be challenging.
 | 
			
		||||
    Also, often times one would like to specify the sixth or seventh
 | 
			
		||||
    template parameter, but use the defaults for the third through
 | 
			
		||||
    fifth. As a solution to these problems we provide a mechanism for
 | 
			
		||||
    naming the last five template parameters, and providing them in
 | 
			
		||||
    any order through the <tt>iterator_traits_generator</tt> class.
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
<a name="iterator_traits_generator">class iterator_traits_generator</a>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  template <class Value>
 | 
			
		||||
  struct value_type : public <i>recursive magic</i> { };
 | 
			
		||||
 | 
			
		||||
  template <class Reference>
 | 
			
		||||
  struct reference : public <i>recursive magic</i> { };
 | 
			
		||||
 | 
			
		||||
  template <class Pointer>
 | 
			
		||||
  struct pointer : public <i>recursive magic</i> { };
 | 
			
		||||
 | 
			
		||||
  template <class Distance>
 | 
			
		||||
  struct difference_type : public <i>recursive magic</i> { };
 | 
			
		||||
 | 
			
		||||
  template <class Category>
 | 
			
		||||
  struct iterator_category : public <i>recursive magic</i> { };
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    The <tt>iterator_traits_generator</tt> is used to create a list of
 | 
			
		||||
    of template arguments. For example, suppose you want to set the
 | 
			
		||||
    <tt>Reference</tt> and <tt>Category</tt> parameters, and use the
 | 
			
		||||
    defaults for the rest. Then you can use the traits generator as
 | 
			
		||||
    follows:
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
iterator_traits_generator::reference<foo>::category<std::input_iterator_tag>
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    This generated type can then be passed into the <tt>iterator_adaptor</tt>
 | 
			
		||||
    class to replace any of the last five parameters. If you use the traits
 | 
			
		||||
    generator in the <i>i</i>th parameter position, then the parameters <i>i</i>
 | 
			
		||||
    through 7 will use the types specified in the generator. For example, the
 | 
			
		||||
    following adapts <tt>foo_iterator</tt> to create an <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> with
 | 
			
		||||
    <tt>reference</tt> type <tt>foo</tt>, and whose other traits are determined
 | 
			
		||||
    according to the defaults described <a href="#template_parameters">above</a>.
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
iterator_adaptor<foo_iterator, foo_policies,
 | 
			
		||||
    iterator_traits_generator
 | 
			
		||||
    ::reference<foo>
 | 
			
		||||
    ::iterator_category<std::input_iterator_tag>
 | 
			
		||||
>
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    <h3><a name="policies">The Policies Class</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>The main task in using <tt>iterator_adaptor</tt> is creating an
 | 
			
		||||
    appropriate <tt>Policies</tt> class. The <tt>Policies</tt> class will become
 | 
			
		||||
    the functional heart of the resulting iterator, supplying the core
 | 
			
		||||
    operations that determine its behavior. The <tt>iterator_adaptor</tt>
 | 
			
		||||
    template defines all of the operators required of a <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
 | 
			
		||||
    Iterator</a> by dispatching to a <tt>Policies</tt> object. Your
 | 
			
		||||
    <tt>Policies</tt> class must implement a subset of the core iterator
 | 
			
		||||
    operations below corresponding to the iterator categories you want it to
 | 
			
		||||
    support.<br>
 | 
			
		||||
    <br>
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    <table border="1" summary="iterator_adaptor Policies operations">
 | 
			
		||||
      <caption>
 | 
			
		||||
        <b>Core Iterator Operations</b><br>
 | 
			
		||||
        <tt>T</tt>: adapted iterator type; <tt>p</tt>: object of type T; <tt>n</tt>: <tt>T::size_type</tt>; <tt>x</tt>: <tt>T::difference_type</tt>; <tt>p1</tt>, <tt>p2</tt>: iterators
 | 
			
		||||
      </caption>
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <th>Operation
 | 
			
		||||
 | 
			
		||||
        <th>Effects
 | 
			
		||||
 | 
			
		||||
        <th>Implements Operations
 | 
			
		||||
 | 
			
		||||
        <th>Required for Iterator Categories
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>initialize</tt>
 | 
			
		||||
 | 
			
		||||
        <td>optionally modify base iterator during iterator construction
 | 
			
		||||
 | 
			
		||||
        <td>constructors
 | 
			
		||||
 | 
			
		||||
        <td rowspan="4"><a href=
 | 
			
		||||
        "http://www.sgi.com/tech/stl/InputIterator.html">Input</a>/ <a href=
 | 
			
		||||
        "http://www.sgi.com/tech/stl/OutputIterator.html">Output</a>/ <a href=
 | 
			
		||||
        "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward</a>/ <a
 | 
			
		||||
        href=
 | 
			
		||||
        "http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional</a>/
 | 
			
		||||
        <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
        Access</a> 
 | 
			
		||||
 | 
			
		||||
	  
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>dereference</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>returns an element of the iterator's <tt>reference</tt> type
 | 
			
		||||
        
 | 
			
		||||
        <td><tt>*p</tt>, <tt>p[n]</tt>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>equal</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>tests the iterator for equality
 | 
			
		||||
 | 
			
		||||
        <td><tt>p1 == p2</tt>, <tt>p1 != p2</tt>
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>increment</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>increments the iterator
 | 
			
		||||
 | 
			
		||||
        <td><tt>++p</tt>, <tt>p++</tt>
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>decrement</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>decrements the iterator
 | 
			
		||||
 | 
			
		||||
        <td><tt>--p</tt>, <tt>p--</tt>
 | 
			
		||||
 | 
			
		||||
        <td><a href=
 | 
			
		||||
        "http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional</a>/
 | 
			
		||||
        <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
        Access</a> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>less</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>imposes a <a href=
 | 
			
		||||
        "http://www.sgi.com/tech/stl/StrictWeakOrdering.html">Strict Weak
 | 
			
		||||
        Ordering</a> relation on iterators
 | 
			
		||||
 | 
			
		||||
        <td> 
 | 
			
		||||
           <tt>p1 < p2</tt>,
 | 
			
		||||
           <tt>p1 <= p2</tt>,
 | 
			
		||||
           <tt>p1 > p2</tt>,
 | 
			
		||||
           <tt>p1 >= p2</tt>
 | 
			
		||||
 | 
			
		||||
        <td rowspan="3"><a href=
 | 
			
		||||
        "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
        Access</a> 
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>distance</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>measures the distance between iterators
 | 
			
		||||
 | 
			
		||||
        <td><tt>p1 - p2</tt>
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>advance</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>adds an integer offset to iterators
 | 
			
		||||
 | 
			
		||||
        <td>
 | 
			
		||||
<tt>p + x</tt>,
 | 
			
		||||
<tt>x + p</tt>,
 | 
			
		||||
<tt>p += x</tt>,
 | 
			
		||||
<tt>p - x</tt>,
 | 
			
		||||
<tt>p -= x</tt>
 | 
			
		||||
        
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <p>The library also supplies a "trivial" policy class,
 | 
			
		||||
    <tt>default_iterator_policies</tt>, which implements all seven of the core
 | 
			
		||||
    operations in the usual way. If you wish to create an iterator adaptor that
 | 
			
		||||
    only changes a few of the base type's behaviors, then you can derive your
 | 
			
		||||
    new policy class from <tt>default_iterator_policies</tt> to avoid retyping
 | 
			
		||||
    the usual behaviors. You should also look at
 | 
			
		||||
    <tt>default_iterator_policies</tt> as the ``boilerplate'' for your own
 | 
			
		||||
    policy classes, defining functions with the same interface. This is the
 | 
			
		||||
    definition of <tt>default_iterator_policies</tt>:<br>
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
struct <a name="default_iterator_policies">default_iterator_policies</a>
 | 
			
		||||
{
 | 
			
		||||
  template <class BaseType>
 | 
			
		||||
  void initialize(BaseType&)
 | 
			
		||||
    { }
 | 
			
		||||
 | 
			
		||||
  template <class Reference, class BaseType>
 | 
			
		||||
  Reference dereference(type<Reference>, const BaseType& x) const
 | 
			
		||||
    { return *x; }
 | 
			
		||||
 | 
			
		||||
  template <class BaseType>
 | 
			
		||||
  static void increment(BaseType& x)
 | 
			
		||||
    { ++x; }
 | 
			
		||||
 | 
			
		||||
  template <class BaseType1, class BaseType2>
 | 
			
		||||
  bool equal(BaseType1& x, BaseType2& y) const
 | 
			
		||||
    { return x == y; }
 | 
			
		||||
 | 
			
		||||
  template <class BaseType>
 | 
			
		||||
  static void decrement(BaseType& x)
 | 
			
		||||
    { --x; }
 | 
			
		||||
 | 
			
		||||
  template <class BaseType, class DifferenceType>
 | 
			
		||||
  static void advance(BaseType& x, DifferenceType n)
 | 
			
		||||
    { x += n; }
 | 
			
		||||
 | 
			
		||||
  template <class Difference, class BaseType1, class BaseType2>
 | 
			
		||||
  Difference distance(type<Difference>, BaseType1& x, BaseType2& y) const
 | 
			
		||||
    { return y - x; }
 | 
			
		||||
 | 
			
		||||
  template <class BaseType1, class BaseType2>
 | 
			
		||||
  bool less(BaseType1& x, BaseType2& y) const
 | 
			
		||||
    { return x < y; }
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <p>Template member functions are used throughout
 | 
			
		||||
    <tt>default_iterator_policies</tt> so that it can be employed with a wide
 | 
			
		||||
    range of iterators. If we had used concrete types above, we'd have tied the
 | 
			
		||||
    usefulness of <tt>default_iterator_policies</tt> to a particular range of
 | 
			
		||||
    adapted iterators. If you follow the same pattern with your
 | 
			
		||||
    <tt>Policies</tt> classes, you can use them to generate more specialized
 | 
			
		||||
    adaptors along the lines of <a href="#specialized_adaptors">those supplied by this library</a>.
 | 
			
		||||
 | 
			
		||||
    <h3><a name="additional_members">Additional Members</a></h3>
 | 
			
		||||
    In addition to all of the member functions required of a <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
 | 
			
		||||
    Iterator</a>, the <tt>iterator_adaptor</tt> class template defines the
 | 
			
		||||
    following members. <br>
 | 
			
		||||
     <br>
 | 
			
		||||
     
 | 
			
		||||
 | 
			
		||||
    <table border="1" summary="additional iterator_adaptor members">
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>explicit iterator_adaptor(const Base&, const Policies& =
 | 
			
		||||
        Policies())</tt>
 | 
			
		||||
         <br><br>
 | 
			
		||||
         Construct an adapted iterator from a base object and a policies
 | 
			
		||||
         object. As this constructor is <tt>explicit</tt>, it does not
 | 
			
		||||
         provide for implicit conversions from the <tt>Base</tt> type to
 | 
			
		||||
         the iterator adaptor.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>template <class B, class V, class R, class P><br>
 | 
			
		||||
         iterator_adaptor(const
 | 
			
		||||
        iterator_adaptor<B,Policies,V,R,P,Category,Distance>&)</tt>
 | 
			
		||||
        <br><br>
 | 
			
		||||
         This constructor allows for conversion from non-<tt>const</tt> to
 | 
			
		||||
        constant adapted iterators. See <a href=
 | 
			
		||||
        "#iterator_interactions">below</a> for more details.<br>
 | 
			
		||||
         Requires: <tt>B</tt> is convertible to <tt>Base</tt>.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>base_type base() const;</tt>
 | 
			
		||||
         <br><br>
 | 
			
		||||
         Return a copy of the base object.
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3><a name="example">Example</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>It is often useful to automatically apply some function to the value
 | 
			
		||||
    returned by dereferencing an iterator. The <a href=
 | 
			
		||||
    "./transform_iterator.htm">transform iterator</a> makes it easy to create
 | 
			
		||||
    an iterator adaptor which does just that. Here we will show how easy it is
 | 
			
		||||
    to implement the transform iterator using the <tt>iterator_adaptor</tt>
 | 
			
		||||
    template.
 | 
			
		||||
 | 
			
		||||
    <p>We want to be able to adapt a range of iterators and functions, so the
 | 
			
		||||
    policies class will have a template parameter for the function type and it
 | 
			
		||||
    will have a data member of that type. We know that the function takes one
 | 
			
		||||
    argument and that we'll need to be able to deduce the <tt>result_type</tt>
 | 
			
		||||
    of the function so we can use it for the adapted iterator's
 | 
			
		||||
    <tt>value_type</tt>. <a href=
 | 
			
		||||
    "http://www.sgi.com/Technology/STL/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>
 | 
			
		||||
    is the <a href="../../more/generic_programming.html#concept">Concept</a>
 | 
			
		||||
    that fulfills those requirements.
 | 
			
		||||
 | 
			
		||||
    <p>To implement a transform iterator we will only change one of the base
 | 
			
		||||
    iterator's behaviors, so the <tt>transform_iterator_policies</tt> class can
 | 
			
		||||
    inherit the rest from <tt>default_iterator_policies</tt>. We will define
 | 
			
		||||
    the <tt>dereference()</tt> member function, which is used to implement
 | 
			
		||||
    <tt>operator*()</tt> of the adapted iterator. The implementation will
 | 
			
		||||
    dereference the base iterator and apply the function object. The
 | 
			
		||||
    <tt>type<Reference></tt> parameter is used to convey the appropriate
 | 
			
		||||
    return type. The complete code for <tt>transform_iterator_policies</tt>
 | 
			
		||||
    is:<br>
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
  template <class AdaptableUnaryFunction>
 | 
			
		||||
  struct transform_iterator_policies : public default_iterator_policies
 | 
			
		||||
  {
 | 
			
		||||
    transform_iterator_policies() { }
 | 
			
		||||
 | 
			
		||||
    transform_iterator_policies(const AdaptableUnaryFunction& f)
 | 
			
		||||
      : m_f(f) { }
 | 
			
		||||
 | 
			
		||||
    template <class Reference, class BaseIterator>
 | 
			
		||||
    Reference dereference(type<Reference>, const BaseIterator& i) const
 | 
			
		||||
      { return m_f(*i); }
 | 
			
		||||
 | 
			
		||||
    AdaptableUnaryFunction m_f;
 | 
			
		||||
  };
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <p>The next step is to use the <tt>iterator_adaptor</tt> template to
 | 
			
		||||
    construct the transform iterator type. The nicest way to package the
 | 
			
		||||
    construction of the transform iterator is to create a <a href=
 | 
			
		||||
    "../../more/generic_programming.html#type_generator">type generator</a>.
 | 
			
		||||
    The first template parameter to the generator will be the type of the
 | 
			
		||||
    function object and the second will be the base iterator type. We use
 | 
			
		||||
    <tt>iterator_adaptor</tt> to define the transform iterator type as a nested
 | 
			
		||||
    <tt>typedef</tt> inside the <tt>transform_iterator_generator</tt> class.
 | 
			
		||||
    Because the function may return by-value, we must limit the
 | 
			
		||||
    <tt>iterator_category</tt> to <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>, and
 | 
			
		||||
    the iterator's <tt>reference</tt> type cannot be a true reference (the
 | 
			
		||||
    standard allows this for input iterators), so in this case we can use few
 | 
			
		||||
    of <tt>iterator_adaptor</tt>'s default template arguments.<br>
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class AdaptableUnaryFunction, class Iterator>
 | 
			
		||||
struct transform_iterator_generator
 | 
			
		||||
{
 | 
			
		||||
    typedef typename AdaptableUnaryFunction::result_type value_type;
 | 
			
		||||
public:
 | 
			
		||||
    typedef iterator_adaptor<Iterator, 
 | 
			
		||||
        transform_iterator_policies<AdaptableUnaryFunction>,
 | 
			
		||||
        value_type, value_type, value_type*, std::input_iterator_tag>
 | 
			
		||||
      type;
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <p>As a finishing touch, we will create an <a href=
 | 
			
		||||
    "../../more/generic_programming.html#object_generator">object generator</a>
 | 
			
		||||
    for the transform iterator. This is a function that makes it more
 | 
			
		||||
    convenient to create a transform iterator.<br>
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class AdaptableUnaryFunction, class Iterator>
 | 
			
		||||
typename transform_iterator_generator<AdaptableUnaryFunction,Iterator>::type
 | 
			
		||||
make_transform_iterator(Iterator base,
 | 
			
		||||
                        const AdaptableUnaryFunction& f = AdaptableUnaryFunction())
 | 
			
		||||
{
 | 
			
		||||
    typedef typename transform_iterator_generator<AdaptableUnaryFunction,
 | 
			
		||||
      Iterator>::type result_t;
 | 
			
		||||
    return result_t(base, f);
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <p>Here is an example that shows how to use a transform iterator to iterate
 | 
			
		||||
    through a range of numbers, multiplying each of them by 2 and printing the
 | 
			
		||||
    result to standard output.<br>
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
 | 
			
		||||
  const int N = sizeof(x)/sizeof(int);
 | 
			
		||||
  std::cout << "multiplying the array by 2:" << std::endl;
 | 
			
		||||
  std::copy(boost::make_transform_iterator(x, std::bind1st(std::multiplies<int>(), 2)),
 | 
			
		||||
      boost::make_transform_iterator(x + N, std::bind1st(std::multiplies<int>(), 2)),
 | 
			
		||||
      std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
      This output is: 
 | 
			
		||||
<pre>
 | 
			
		||||
2 4 6 8 10 12 14 16
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3><a name="iterator_interactions">Iterator Interactions</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>C++ allows <tt>const</tt> and non-<tt>const</tt> pointers to interact in
 | 
			
		||||
    the following intuitive ways:
 | 
			
		||||
 | 
			
		||||
    <ul>
 | 
			
		||||
      <li>a non-<tt>const</tt> pointer to <tt>T</tt> can be implicitly
 | 
			
		||||
      converted to a <tt>const</tt> pointer to <tt>T</tt>.
 | 
			
		||||
 | 
			
		||||
      <li><tt>const</tt> and non-<tt>const</tt> pointers to <tt>T</tt> can be
 | 
			
		||||
      freely mixed in comparison expressions.
 | 
			
		||||
 | 
			
		||||
      <li><tt>const</tt> and non-<tt>const</tt> pointers to <tt>T</tt> can be
 | 
			
		||||
      freely subtracted, in any order.
 | 
			
		||||
    </ul>
 | 
			
		||||
 | 
			
		||||
    Getting user-defined iterators to work together that way is nontrivial (see
 | 
			
		||||
    <a href="reverse_iterator.htm#interactions">here</a> for an example of where
 | 
			
		||||
    the C++ standard got it wrong), but <tt>iterator_adaptor</tt> can make it
 | 
			
		||||
    easy. The rules are as follows:
 | 
			
		||||
 | 
			
		||||
    <ul>
 | 
			
		||||
      <li><a name="interoperable">Adapted iterators that share the same <tt>Policies</tt>,
 | 
			
		||||
      <tt>Category</tt>, and <tt>Distance</tt> parameters are called
 | 
			
		||||
      <i>interoperable</i>.</a>
 | 
			
		||||
 | 
			
		||||
      <li>An adapted iterator can be implicitly converted to any other adapted
 | 
			
		||||
      iterator with which it is interoperable, so long as the <tt>Base</tt>
 | 
			
		||||
      type of the source iterator can be converted to the <tt>Base</tt> type of
 | 
			
		||||
      the target iterator.
 | 
			
		||||
 | 
			
		||||
      <li>Interoperable iterators can be freely mixed in comparison expressions
 | 
			
		||||
      so long as the <tt>Policies</tt> class has <tt>equal</tt> (and, for
 | 
			
		||||
      random access iterators, <tt>less</tt>) members that can accept both
 | 
			
		||||
      <tt>Base</tt> types in either order.
 | 
			
		||||
 | 
			
		||||
      <li>Interoperable iterators can be freely mixed in subtraction
 | 
			
		||||
      expressions so long as the <tt>Policies</tt> class has a
 | 
			
		||||
      <tt>distance</tt> member that can accept both <tt>Base</tt> types in
 | 
			
		||||
      either order.
 | 
			
		||||
    </ul>
 | 
			
		||||
 | 
			
		||||
    <h4>Example</h4>
 | 
			
		||||
    
 | 
			
		||||
    <p>The <a href="projection_iterator.htm">Projection Iterator</a> adaptor is similar to the <a
 | 
			
		||||
href="./transform_iterator.htm">transform iterator adaptor</a> in that
 | 
			
		||||
its <tt>operator*()</tt> applies some function to the result of
 | 
			
		||||
dereferencing the base iterator and then returns the result. The
 | 
			
		||||
difference is that the function must return a reference to some
 | 
			
		||||
existing object (for example, a data member within the
 | 
			
		||||
<tt>value_type</tt> of the base iterator). 
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
The <a
 | 
			
		||||
    href="projection_iterator.htm#projection_iterator_pair_generator">projection_iterator_pair_generator</a> template
 | 
			
		||||
    is a special two-<a href="../../more/generic_programming.html#type_generator">type generator</a> for mutable and constant versions of a
 | 
			
		||||
    projection iterator. It is defined as follows:
 | 
			
		||||
<blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class AdaptableUnaryFunction, class Iterator, class ConstIterator>
 | 
			
		||||
struct projection_iterator_pair_generator {
 | 
			
		||||
    typedef typename AdaptableUnaryFunction::result_type value_type;
 | 
			
		||||
    typedef projection_iterator_policies<AdaptableUnaryFunction> policies;
 | 
			
		||||
public:
 | 
			
		||||
    typedef iterator_adaptor<Iterator,policies,value_type> iterator;
 | 
			
		||||
    typedef iterator_adaptor<ConstIterator,policies,value_type,
 | 
			
		||||
        const value_type&,const value_type*> const_iterator;
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
</blockquote>
 | 
			
		||||
 | 
			
		||||
<p>It is assumed that the <tt>Iterator</tt> and <tt>ConstIterator</tt> arguments are corresponding mutable
 | 
			
		||||
and constant iterators. <ul>
 | 
			
		||||
<li>
 | 
			
		||||
Clearly, then, the
 | 
			
		||||
<tt>projection_iterator_pair_generator</tt>'s <tt>iterator</tt> and
 | 
			
		||||
<tt>const_iterator</tt> are <a href="#interoperable">interoperable</a>, since
 | 
			
		||||
they share the same <tt>Policies</tt> and since <tt>Category</tt> and
 | 
			
		||||
<tt>Distance</tt> as supplied by <tt>std::iterator_traits</tt> through the
 | 
			
		||||
<a href="#template_parameters">default template parameters</a> to
 | 
			
		||||
<tt>iterator_adaptor</tt> should be the same.
 | 
			
		||||
 | 
			
		||||
<li>Since <tt>Iterator</tt> can presumably be converted to
 | 
			
		||||
<tt>ConstIterator</tt>, the projection <tt>iterator</tt> will be convertible to
 | 
			
		||||
the projection <tt>const_iterator</tt>.
 | 
			
		||||
 | 
			
		||||
<li> Since <tt>projection_iterator_policies</tt> implements only the
 | 
			
		||||
<tt>dereference</tt> operation, and inherits all other behaviors from <tt><a
 | 
			
		||||
href="#default_iterator_policies">default_iterator_policies</a></tt>, which has
 | 
			
		||||
fully-templatized <tt>equal</tt>, <tt>less</tt>, and <tt>distance</tt>
 | 
			
		||||
operations, the <tt>iterator</tt> and <tt>const_iterator</tt> can be freely
 | 
			
		||||
mixed in comparison and subtraction expressions.
 | 
			
		||||
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
    <h3><a name="challenge">Challenge</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p>There is an unlimited number of ways the <tt>iterator_adaptors</tt>
 | 
			
		||||
    class can be used to create iterators. One interesting exercise would be to
 | 
			
		||||
    re-implement the iterators of <tt>std::list</tt> and <tt>std::slist</tt>
 | 
			
		||||
    using <tt>iterator_adaptors</tt>, where the adapted <tt>Iterator</tt> types
 | 
			
		||||
    would be node pointers.
 | 
			
		||||
 | 
			
		||||
    <h3><a name="concept_model">Concept Model</a></h3>
 | 
			
		||||
    Depending on the <tt>Base</tt> and <tt>Policies</tt> template parameters,
 | 
			
		||||
    an <tt>iterator_adaptor</tt> can be a <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>, <a
 | 
			
		||||
    href="http://www.sgi.com/tech/stl/ForwardIterator.html">Forward
 | 
			
		||||
    Iterator</a>, <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional
 | 
			
		||||
    Iterator</a>, or <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
 | 
			
		||||
    Iterator</a>. 
 | 
			
		||||
 | 
			
		||||
    <h3><a name="declaration_synopsis">Declaration Synopsis</a></h3>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class Base, class Policies, 
 | 
			
		||||
    class Value = typename std::iterator_traits<Base>::value_type,
 | 
			
		||||
    class Reference = <i>...(see below)</i>,
 | 
			
		||||
    class Pointer = <i>...(see below)</i>,
 | 
			
		||||
    class Category = typename std::iterator_traits<Base>::iterator_category,
 | 
			
		||||
    class Distance = typename std::iterator_traits<Base>::difference_type
 | 
			
		||||
         >
 | 
			
		||||
struct iterator_adaptor
 | 
			
		||||
{
 | 
			
		||||
    typedef Distance difference_type;
 | 
			
		||||
    typedef typename boost::remove_const<Value>::type value_type;
 | 
			
		||||
    typedef Pointer pointer;
 | 
			
		||||
    typedef Reference reference;
 | 
			
		||||
    typedef Category iterator_category;
 | 
			
		||||
    typedef Base base_type;
 | 
			
		||||
    typedef Policies policies_type;
 | 
			
		||||
 | 
			
		||||
    iterator_adaptor();
 | 
			
		||||
    explicit iterator_adaptor(const Base&, const Policies& = Policies());
 | 
			
		||||
 | 
			
		||||
    base_type base() const;
 | 
			
		||||
 | 
			
		||||
    template <class B, class V, class R, class P>
 | 
			
		||||
    iterator_adaptor(
 | 
			
		||||
        const iterator_adaptor<B,Policies,V,R,P,Category,Distance>&);
 | 
			
		||||
 | 
			
		||||
    reference operator*() const;
 | 
			
		||||
    <i>operator_arrow_result_type</i> operator->() const; <a href=
 | 
			
		||||
"#3">[3]</a>
 | 
			
		||||
    <i>value_type</i> operator[](difference_type n) const; <a href="#3">[4]</a>
 | 
			
		||||
 | 
			
		||||
    iterator_adaptor& operator++();
 | 
			
		||||
    iterator_adaptor& operator++(int);
 | 
			
		||||
    iterator_adaptor& operator--();
 | 
			
		||||
    iterator_adaptor& operator--(int);
 | 
			
		||||
 | 
			
		||||
    iterator_adaptor& operator+=(difference_type n);
 | 
			
		||||
    iterator_adaptor& operator-=(difference_type n);
 | 
			
		||||
 | 
			
		||||
    iterator_adaptor& operator-(Distance x) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class B, class P, class V, class R, class Ptr, 
 | 
			
		||||
    class C, class D1, class D2>
 | 
			
		||||
iterator_adaptor<B,P,V,R,Ptr,C,D1>
 | 
			
		||||
operator+(iterator_adaptor<B,P,V,R,Ptr,C,D1>, D2);
 | 
			
		||||
 | 
			
		||||
template <class B, class P, class V, class R, class Ptr,
 | 
			
		||||
    class C, class D1, class D2>
 | 
			
		||||
iterator_adaptor<B,P,V,R,P,C,D1>
 | 
			
		||||
operator+(D2, iterator_adaptor<B,P,V,R,Ptr,C,D1> p);
 | 
			
		||||
 | 
			
		||||
template <class B1, class B2, class P, class V1, class V2,
 | 
			
		||||
    class R1, class R2, class P1, class P2, class C, class D>
 | 
			
		||||
Distance operator-(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&, 
 | 
			
		||||
                   const iterator_adaptor<B2,P,V2,R2,P2,C,D>&);
 | 
			
		||||
 | 
			
		||||
template <class B1, class B2, class P, class V1, class V2,
 | 
			
		||||
    class R1, class R2, class P1, class P2, class C, class D>
 | 
			
		||||
bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&, 
 | 
			
		||||
                const iterator_adaptor<B2,P,V2,R2,P2,C,D>&);
 | 
			
		||||
 | 
			
		||||
// and similarly for operators !=, <, <=, >=, >
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
    <h3><a name="notes">Notes</a></h3>
 | 
			
		||||
 | 
			
		||||
    <p><a name="1">[1]</a> The standard specifies that the <tt>value_type</tt>
 | 
			
		||||
    of <tt>const</tt> iterators to <tt>T</tt> (e.g. <tt>const T*</tt>) is
 | 
			
		||||
    <tt><i>non-</i>const T</tt>, while the <tt>pointer</tt> and
 | 
			
		||||
    <tt>reference</tt> types for all <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterators</a> are
 | 
			
		||||
    <tt>const T*</tt> and <tt>const T&</tt>, respectively. Stripping the
 | 
			
		||||
    <tt>const</tt>-ness of <tt>Value</tt> allows you to easily
 | 
			
		||||
    make a <tt>const</tt> iterator adaptor by supplying a <tt>const</tt> type
 | 
			
		||||
    for <tt>Value</tt>, and allowing the defaults for the <tt>Pointer</tt> and
 | 
			
		||||
    <tt>Reference</tt> parameters to take effect. Although compilers that don't
 | 
			
		||||
    support partial specialization won't strip <tt>const</tt> for you, having a
 | 
			
		||||
    <tt>const value_type</tt> is often harmless in practice.
 | 
			
		||||
 | 
			
		||||
    <p><a name="2">[2]</a> If your compiler does not support partial
 | 
			
		||||
    specialization and the base iterator is a builtin pointer type, you
 | 
			
		||||
    will not be able to use the default for <tt>Value</tt> and will have to
 | 
			
		||||
    specify this type explicitly.
 | 
			
		||||
 | 
			
		||||
    <p><a name="3">[3]</a> The result type for the <tt>operator->()</tt>
 | 
			
		||||
    depends on the category and value type of the iterator and is somewhat
 | 
			
		||||
    complicated to describe. But be assured, it works in a stardard conforming
 | 
			
		||||
    fashion, providing access to members of the objects pointed to by the
 | 
			
		||||
    iterator.
 | 
			
		||||
 | 
			
		||||
    <p><a name="4">[4]</a> The result type of <tt>operator[]()</tt> is
 | 
			
		||||
    <tt>value_type</tt> instead of <tt>reference</tt> as might be expected.
 | 
			
		||||
    There are two reasons for this choice. First, the C++ standard only
 | 
			
		||||
    requires that the return type of an arbitrary <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
 | 
			
		||||
    Iterator</a>'s <tt>operator[]</tt>be ``convertible to T'' (Table 76), so
 | 
			
		||||
    when adapting an arbitrary base iterator we may not have a reference to
 | 
			
		||||
    return. Second, and more importantly, for certain kinds of iterators,
 | 
			
		||||
    returning a reference could cause serious memory problems due to the
 | 
			
		||||
    reference being bound to a temporary object whose lifetime ends inside of
 | 
			
		||||
    the <tt>operator[]</tt>.
 | 
			
		||||
 | 
			
		||||
    <p><a name="5">[5]</a>
 | 
			
		||||
    The <tt>value_type</tt> of an iterator may not be
 | 
			
		||||
    an abstract base class, however many common uses of iterators
 | 
			
		||||
    never need the <tt>value_type</tt>, only the <tt>reference</tt> type.
 | 
			
		||||
    If you wish to create such an iterator adaptor, use a dummy
 | 
			
		||||
    type such as <tt>char</tt> for the <tt>Value</tt> parameter,
 | 
			
		||||
    and use a reference to your abstract base class for
 | 
			
		||||
    the <tt>Reference</tt> parameter. Note that such an iterator
 | 
			
		||||
    does not fulfill the C++ standards requirements for a
 | 
			
		||||
    <a href= "http://www.sgi.com/tech/stl/ForwardIterator.html">
 | 
			
		||||
    Forward Iterator</a>, so you will need to use a less restrictive
 | 
			
		||||
    iterator category such as <tt>std::input_iterator_tag</tt>.
 | 
			
		||||
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <p>Revised 
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->12 Jul 2001<!--webbot bot="Timestamp" endspan i-checksum="14985" -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <p>© Copyright Dave Abrahams and Jeremy Siek 2001. Permission to copy,
 | 
			
		||||
    use, modify, sell and distribute this document is granted provided this
 | 
			
		||||
    copyright notice appears in all copies. This document is provided "as is"
 | 
			
		||||
    without express or implied warranty, and with no claim as to its
 | 
			
		||||
    suitability for any purpose. 
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
This documentation moved to <a href="../iterator/doc/index.html">../iterator/doc/index.html</a>.
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
    <!--  LocalWords:  HTML html charset alt gif abrahams htm const
 | 
			
		||||
        incrementable david abrahams
 | 
			
		||||
         -->
 | 
			
		||||
     
 | 
			
		||||
    <!--  LocalWords:  jeremy siek mishandled interoperable typename struct Iter iter src
 | 
			
		||||
         -->
 | 
			
		||||
     
 | 
			
		||||
    <!--  LocalWords:  int bool ForwardIterator BidirectionalIterator BaseIterator
 | 
			
		||||
         -->
 | 
			
		||||
     
 | 
			
		||||
    <!--  LocalWords:  RandomAccessIterator DifferenceType AdaptableUnaryFunction
 | 
			
		||||
         -->
 | 
			
		||||
     
 | 
			
		||||
    <!--  LocalWords:  iostream hpp sizeof InputIterator constness ConstIterator
 | 
			
		||||
         David Abrahams
 | 
			
		||||
         -->
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,210 +0,0 @@
 | 
			
		||||
//  (C) Copyright David Abrahams 2001. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  04 Mar 2001 Patches for Intel C++ (Dave Abrahams)
 | 
			
		||||
//  19 Feb 2001 Take advantage of improved iterator_traits to do more tests
 | 
			
		||||
//              on MSVC. Reordered some #ifdefs for coherency.
 | 
			
		||||
//              (David Abrahams)
 | 
			
		||||
//  13 Feb 2001 Test new VC6 workarounds (David Abrahams)
 | 
			
		||||
//  11 Feb 2001 Final fixes for Borland (David Abrahams)
 | 
			
		||||
//  11 Feb 2001 Some fixes for Borland get it closer on that compiler
 | 
			
		||||
//              (David Abrahams)
 | 
			
		||||
//  07 Feb 2001 More comprehensive testing; factored out static tests for
 | 
			
		||||
//              better reuse (David Abrahams)
 | 
			
		||||
//  21 Jan 2001 Quick fix to my_iterator, which wasn't returning a
 | 
			
		||||
//              reference type from operator* (David Abrahams)
 | 
			
		||||
//  19 Jan 2001 Initial version with iterator operators (David Abrahams)
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/iterator.hpp>
 | 
			
		||||
#include <boost/type_traits.hpp>
 | 
			
		||||
#include <boost/operators.hpp>
 | 
			
		||||
#include <boost/static_assert.hpp>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
// An iterator for which we can get traits.
 | 
			
		||||
struct my_iterator1
 | 
			
		||||
    : boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&>
 | 
			
		||||
{
 | 
			
		||||
    my_iterator1(const char* p) : m_p(p) {}
 | 
			
		||||
    
 | 
			
		||||
    bool operator==(const my_iterator1& rhs) const
 | 
			
		||||
        { return this->m_p == rhs.m_p; }
 | 
			
		||||
 | 
			
		||||
    my_iterator1& operator++() { ++this->m_p; return *this; }
 | 
			
		||||
    const char& operator*() { return *m_p; }
 | 
			
		||||
 private:
 | 
			
		||||
    const char* m_p;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Used to prove that we don't require std::iterator<> in the hierarchy under
 | 
			
		||||
// MSVC6, and that we can compute all the traits for a standard-conforming UDT
 | 
			
		||||
// iterator.
 | 
			
		||||
struct my_iterator2
 | 
			
		||||
    : boost::equality_comparable<my_iterator2
 | 
			
		||||
    , boost::incrementable<my_iterator2
 | 
			
		||||
    , boost::dereferenceable<my_iterator2,const char*> > >
 | 
			
		||||
{
 | 
			
		||||
    typedef char value_type;
 | 
			
		||||
    typedef long difference_type;
 | 
			
		||||
    typedef const char* pointer;
 | 
			
		||||
    typedef const char& reference;
 | 
			
		||||
    typedef std::forward_iterator_tag iterator_category;
 | 
			
		||||
    
 | 
			
		||||
    my_iterator2(const char* p) : m_p(p) {}
 | 
			
		||||
    
 | 
			
		||||
    bool operator==(const my_iterator2& rhs) const
 | 
			
		||||
        { return this->m_p == rhs.m_p; }
 | 
			
		||||
 | 
			
		||||
    my_iterator2& operator++() { ++this->m_p; return *this; }
 | 
			
		||||
    const char& operator*() { return *m_p; }
 | 
			
		||||
 private:
 | 
			
		||||
    const char* m_p;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Used to prove that we're not overly confused by the existence of
 | 
			
		||||
// std::iterator<> in the hierarchy under MSVC6 - we should find that
 | 
			
		||||
// boost::detail::iterator_traits<my_iterator3>::difference_type is int.
 | 
			
		||||
struct my_iterator3 : my_iterator1
 | 
			
		||||
{
 | 
			
		||||
    typedef int difference_type;
 | 
			
		||||
    my_iterator3(const char* p) : my_iterator1(p) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Iterator,
 | 
			
		||||
    class value_type, class difference_type, class pointer, class reference, class category>
 | 
			
		||||
struct non_portable_tests
 | 
			
		||||
{
 | 
			
		||||
    // Unfortunately, the VC6 standard library doesn't supply these :(
 | 
			
		||||
    BOOST_STATIC_ASSERT((
 | 
			
		||||
        boost::is_same<
 | 
			
		||||
        typename boost::detail::iterator_traits<Iterator>::pointer,
 | 
			
		||||
        pointer
 | 
			
		||||
        >::value));
 | 
			
		||||
    
 | 
			
		||||
    BOOST_STATIC_ASSERT((
 | 
			
		||||
        boost::is_same<
 | 
			
		||||
        typename boost::detail::iterator_traits<Iterator>::reference,
 | 
			
		||||
        reference
 | 
			
		||||
        >::value));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Iterator,
 | 
			
		||||
    class value_type, class difference_type, class pointer, class reference, class category>
 | 
			
		||||
struct portable_tests
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_ASSERT((
 | 
			
		||||
        boost::is_same<
 | 
			
		||||
        typename boost::detail::iterator_traits<Iterator>::difference_type,
 | 
			
		||||
        difference_type
 | 
			
		||||
        >::value));
 | 
			
		||||
    
 | 
			
		||||
    BOOST_STATIC_ASSERT((
 | 
			
		||||
        boost::is_same<
 | 
			
		||||
        typename boost::detail::iterator_traits<Iterator>::iterator_category,
 | 
			
		||||
        category
 | 
			
		||||
        >::value));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Test iterator_traits
 | 
			
		||||
template <class Iterator,
 | 
			
		||||
    class value_type, class difference_type, class pointer, class reference, class category>
 | 
			
		||||
struct input_iterator_test
 | 
			
		||||
    : portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_ASSERT((
 | 
			
		||||
        boost::is_same<
 | 
			
		||||
        typename boost::detail::iterator_traits<Iterator>::value_type,
 | 
			
		||||
        value_type
 | 
			
		||||
        >::value));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Iterator,
 | 
			
		||||
    class value_type, class difference_type, class pointer, class reference, class category>
 | 
			
		||||
struct non_pointer_test
 | 
			
		||||
    : input_iterator_test<Iterator,value_type,difference_type,pointer,reference,category>
 | 
			
		||||
      , non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Iterator,
 | 
			
		||||
    class value_type, class difference_type, class pointer, class reference, class category>
 | 
			
		||||
struct maybe_pointer_test
 | 
			
		||||
    : portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
      , non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag>
 | 
			
		||||
        istream_iterator_test;
 | 
			
		||||
 | 
			
		||||
// 
 | 
			
		||||
#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT)
 | 
			
		||||
typedef ::std::char_traits<char>::off_type distance;
 | 
			
		||||
non_pointer_test<std::ostream_iterator<int>,int,
 | 
			
		||||
    distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
 | 
			
		||||
#elif defined(BOOST_MSVC_STD_ITERATOR)
 | 
			
		||||
non_pointer_test<std::ostream_iterator<int>,
 | 
			
		||||
    int, void, void, void, std::output_iterator_tag>
 | 
			
		||||
        ostream_iterator_test;
 | 
			
		||||
#else
 | 
			
		||||
non_pointer_test<std::ostream_iterator<int>,
 | 
			
		||||
    void, void, void, void, std::output_iterator_tag>
 | 
			
		||||
        ostream_iterator_test;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __KCC
 | 
			
		||||
  typedef long std_list_diff_type;
 | 
			
		||||
#else
 | 
			
		||||
  typedef std::ptrdiff_t std_list_diff_type;
 | 
			
		||||
#endif
 | 
			
		||||
non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag>
 | 
			
		||||
        list_iterator_test;
 | 
			
		||||
 | 
			
		||||
maybe_pointer_test<std::vector<int>::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
 | 
			
		||||
        vector_iterator_test;
 | 
			
		||||
 | 
			
		||||
maybe_pointer_test<int*, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
 | 
			
		||||
        int_pointer_test;
 | 
			
		||||
 | 
			
		||||
non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forward_iterator_tag>
 | 
			
		||||
       my_iterator1_test;
 | 
			
		||||
                    
 | 
			
		||||
non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag>
 | 
			
		||||
       my_iterator2_test;
 | 
			
		||||
                    
 | 
			
		||||
non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag>
 | 
			
		||||
       my_iterator3_test;
 | 
			
		||||
                    
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    char chars[100];
 | 
			
		||||
    int ints[100];
 | 
			
		||||
    
 | 
			
		||||
    for (std::ptrdiff_t length = 3; length < 100; length += length / 3)
 | 
			
		||||
    {
 | 
			
		||||
        std::list<int> l(length);
 | 
			
		||||
        assert(boost::detail::distance(l.begin(), l.end()) == length);
 | 
			
		||||
        
 | 
			
		||||
        std::vector<int> v(length);
 | 
			
		||||
        assert(boost::detail::distance(v.begin(), v.end()) == length);
 | 
			
		||||
 | 
			
		||||
        assert(boost::detail::distance(&ints[0], ints + length) == length);
 | 
			
		||||
        assert(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length);
 | 
			
		||||
        assert(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length);
 | 
			
		||||
        assert(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +1,9 @@
 | 
			
		||||
//  Demonstrate and test boost/operators.hpp on std::iterators  --------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
//  (C) Copyright Jeremy Siek 1999.
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
@@ -24,7 +23,7 @@
 | 
			
		||||
#include <cstring>    // for std::strcmp
 | 
			
		||||
#include <iostream>   // for std::cout (std::endl, ends, and flush indirectly)
 | 
			
		||||
#include <string>     // for std::string
 | 
			
		||||
#include <strstream>  // for std::ostrstream
 | 
			
		||||
#include <sstream>    // for std::stringstream
 | 
			
		||||
 | 
			
		||||
# ifdef BOOST_NO_STDC_NAMESPACE
 | 
			
		||||
    namespace std { using ::strcmp; }
 | 
			
		||||
@@ -65,16 +64,18 @@ class test_opr_base
 | 
			
		||||
protected:
 | 
			
		||||
    // Test data and types
 | 
			
		||||
    BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u );
 | 
			
		||||
    BOOST_STATIC_CONSTANT( std::size_t, scratch_length = 40u );
 | 
			
		||||
 | 
			
		||||
    typedef std::string  fruit_array_type[ fruit_length ];
 | 
			
		||||
    typedef char         scratch_array_type[ scratch_length ];
 | 
			
		||||
 | 
			
		||||
    static  fruit_array_type    fruit;
 | 
			
		||||
    static  scratch_array_type  scratch;
 | 
			
		||||
 | 
			
		||||
};  // 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
 | 
			
		||||
@@ -94,7 +95,8 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    // Test data
 | 
			
		||||
    static  iter_type const  fruit_begin, fruit_end;
 | 
			
		||||
    static iter_type const  fruit_begin;
 | 
			
		||||
    static iter_type const  fruit_end;
 | 
			
		||||
 | 
			
		||||
    // Test parts
 | 
			
		||||
    static  void  post_increment_test();
 | 
			
		||||
@@ -113,16 +115,13 @@ private:
 | 
			
		||||
test_opr_base::fruit_array_type
 | 
			
		||||
 test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" };
 | 
			
		||||
 | 
			
		||||
test_opr_base::scratch_array_type
 | 
			
		||||
 test_opr_base::scratch = "";
 | 
			
		||||
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_begin( fruit );
 | 
			
		||||
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
typename test_opr<T, R, P>::iter_type const
 | 
			
		||||
 test_opr<T, R, P>::fruit_end( fruit + fruit_length );
 | 
			
		||||
 test_opr<T, R, P>::fruit_end = test_iter<T,R,P>( fruit + fruit_length );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Main testing function
 | 
			
		||||
@@ -169,15 +168,13 @@ test_opr<T, R, P>::post_increment_test
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing post-increment test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ostrstream  oss( scratch, scratch_length );
 | 
			
		||||
    std::stringstream oss;
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; )
 | 
			
		||||
    {
 | 
			
		||||
        oss << *i++ << ' ';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
 | 
			
		||||
     == 0 );
 | 
			
		||||
    BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test post-decrement
 | 
			
		||||
@@ -189,16 +186,14 @@ test_opr<T, R, P>::post_decrement_test
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing post-decrement test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ostrstream  oss( scratch, scratch_length );
 | 
			
		||||
    std::stringstream oss;
 | 
			
		||||
    for ( iter_type i = fruit_end ; i != fruit_begin ; )
 | 
			
		||||
    {
 | 
			
		||||
        i--;
 | 
			
		||||
        oss << *i << ' ';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "plum grape peach pear orange apple ")
 | 
			
		||||
     == 0 );
 | 
			
		||||
    BOOST_CHECK( oss.str() == "plum grape peach pear orange apple ");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test indirect structure referral
 | 
			
		||||
@@ -210,14 +205,13 @@ test_opr<T, R, P>::indirect_referral_test
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing indirect reference test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ostrstream  oss( scratch, scratch_length );
 | 
			
		||||
    std::stringstream oss;
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        oss << i->size() << ' ';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "5 6 4 5 5 4 ") == 0 );
 | 
			
		||||
    BOOST_CHECK( oss.str() == "5 6 4 5 5 4 ");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test offset addition
 | 
			
		||||
@@ -230,14 +224,13 @@ test_opr<T, R, P>::offset_addition_test
 | 
			
		||||
    std::cout << "\tDoing offset addition test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ptrdiff_t const  two = 2;
 | 
			
		||||
    std::ostrstream       oss( scratch, scratch_length );
 | 
			
		||||
    std::stringstream oss;
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; i = i + two )
 | 
			
		||||
    {
 | 
			
		||||
        oss << *i << ' ';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
 | 
			
		||||
    BOOST_CHECK( oss.str() == "apple pear grape ");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test offset addition, in reverse order
 | 
			
		||||
@@ -250,14 +243,13 @@ 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::ostrstream       oss( scratch, scratch_length );
 | 
			
		||||
    std::stringstream oss;
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; i = two + i )
 | 
			
		||||
    {
 | 
			
		||||
        oss << *i << ' ';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
 | 
			
		||||
    BOOST_CHECK( oss.str() == "apple pear grape ");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test offset subtraction
 | 
			
		||||
@@ -270,7 +262,7 @@ test_opr<T, R, P>::offset_subtraction_test
 | 
			
		||||
    std::cout << "\tDoing offset subtraction test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ptrdiff_t const  two = 2;
 | 
			
		||||
    std::ostrstream       oss( scratch, scratch_length );
 | 
			
		||||
    std::stringstream oss;
 | 
			
		||||
    for ( iter_type i = fruit_end ; fruit_begin < i ; )
 | 
			
		||||
    {
 | 
			
		||||
        i = i - two;
 | 
			
		||||
@@ -280,8 +272,7 @@ test_opr<T, R, P>::offset_subtraction_test
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "grape pear apple ") == 0 );
 | 
			
		||||
    BOOST_CHECK( oss.str() == "grape pear apple ");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test comparisons
 | 
			
		||||
@@ -305,10 +296,10 @@ test_opr<T, R, P>::comparison_test
 | 
			
		||||
        {
 | 
			
		||||
            ptrdiff_t const  j_offset = j - fruit_begin;
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( (i != j) == (i_offset != j_offset) );
 | 
			
		||||
            BOOST_TEST( (i > j) == (i_offset > j_offset) );
 | 
			
		||||
            BOOST_TEST( (i <= j) == (i_offset <= j_offset) );
 | 
			
		||||
            BOOST_TEST( (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) );
 | 
			
		||||
            BOOST_CHECK( (i >= j) == (i_offset >= j_offset) );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    cout << std::endl;
 | 
			
		||||
@@ -323,13 +314,11 @@ test_opr<T, R, P>::indexing_test
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing indexing test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ostrstream  oss( scratch, scratch_length );
 | 
			
		||||
    std::stringstream oss;
 | 
			
		||||
    for ( std::size_t k = 0u ; k < fruit_length ; ++k )
 | 
			
		||||
    {
 | 
			
		||||
        oss << fruit_begin[ k ] << ' ';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
 | 
			
		||||
     == 0 );
 | 
			
		||||
    BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
//  boost class noncopyable test program  ------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
 | 
			
		||||
//  and distribute this software is granted provided this copyright
 | 
			
		||||
//  notice appears in all copies. This software is provided "as is" without
 | 
			
		||||
//  express or implied warranty, and with no claim as to its suitability for
 | 
			
		||||
//  any purpose.
 | 
			
		||||
//  (C) Copyright Beman Dawes 1999. Distributed under the Boost
 | 
			
		||||
//  Software License, Version 1.0. (See accompanying file
 | 
			
		||||
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
@@ -12,7 +10,7 @@
 | 
			
		||||
//   9 Jun 99  Add unnamed namespace
 | 
			
		||||
//   2 Jun 99  Initial Version
 | 
			
		||||
 | 
			
		||||
#include <boost/utility.hpp>
 | 
			
		||||
#include <boost/noncopyable.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
//  This program demonstrates compiler errors resulting from trying to copy
 | 
			
		||||
@@ -20,7 +18,7 @@
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
    class DontTreadOnMe : boost::noncopyable
 | 
			
		||||
    class DontTreadOnMe : private boost::noncopyable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
         DontTreadOnMe() { std::cout << "defanged!" << std::endl; }
 | 
			
		||||
@@ -35,4 +33,4 @@ int main()
 | 
			
		||||
    object1 = object2;
 | 
			
		||||
    return 0;
 | 
			
		||||
}   // main
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
//  (C) Copyright David Abrahams 2001. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
//  (C) Copyright David Abrahams 2001.
 | 
			
		||||
// Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
// accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
@@ -58,7 +57,7 @@ struct complement
 | 
			
		||||
    struct traits
 | 
			
		||||
    {
 | 
			
		||||
     private:
 | 
			
		||||
        // indirection through complement_traits_aux neccessary to keep MSVC happy
 | 
			
		||||
        // indirection through complement_traits_aux necessary to keep MSVC happy
 | 
			
		||||
        typedef complement_traits_aux<Number, size - 1> prev;
 | 
			
		||||
     public:
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, max =
 | 
			
		||||
@@ -214,7 +213,7 @@ struct signed_tag {};
 | 
			
		||||
// Tests for unsigned numbers. The extra default Number parameter works around
 | 
			
		||||
// an MSVC bug.
 | 
			
		||||
template <class Number>
 | 
			
		||||
void test_aux(unsigned_tag, Number* = 0)
 | 
			
		||||
void test_aux(unsigned_tag, Number*)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
 | 
			
		||||
    BOOST_STATIC_ASSERT(!boost::detail::is_signed<Number>::value);
 | 
			
		||||
@@ -256,7 +255,7 @@ struct in_range_tag {};
 | 
			
		||||
// This test morsel gets executed for numbers whose difference will always be
 | 
			
		||||
// representable in intmax_t
 | 
			
		||||
template <class Number>
 | 
			
		||||
void signed_test(in_range_tag, Number* = 0)
 | 
			
		||||
void signed_test(in_range_tag, Number*)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
 | 
			
		||||
    typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
 | 
			
		||||
@@ -277,7 +276,7 @@ void signed_test(in_range_tag, Number* = 0)
 | 
			
		||||
// This test morsel gets executed for numbers whose difference may exceed the
 | 
			
		||||
// capacity of intmax_t.
 | 
			
		||||
template <class Number>
 | 
			
		||||
void signed_test(out_of_range_tag, Number* = 0)
 | 
			
		||||
void signed_test(out_of_range_tag, Number*)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
 | 
			
		||||
    typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
 | 
			
		||||
@@ -301,7 +300,7 @@ void signed_test(out_of_range_tag, Number* = 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Number>
 | 
			
		||||
void test_aux(signed_tag, Number* = 0)
 | 
			
		||||
void test_aux(signed_tag, Number*)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
 | 
			
		||||
    BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
 | 
			
		||||
@@ -328,7 +327,7 @@ void test_aux(signed_tag, Number* = 0)
 | 
			
		||||
                          out_of_range_tag
 | 
			
		||||
                        >::type
 | 
			
		||||
        range_tag;
 | 
			
		||||
    signed_test<Number>(range_tag());
 | 
			
		||||
    signed_test<Number>(range_tag(), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -347,7 +346,7 @@ void test(Number* = 0)
 | 
			
		||||
 | 
			
		||||
    // factoring out difference_type for the assert below confused Borland :(
 | 
			
		||||
    typedef boost::detail::is_signed<
 | 
			
		||||
#ifndef BOOST_MSVC
 | 
			
		||||
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
 | 
			
		||||
        typename
 | 
			
		||||
#endif
 | 
			
		||||
        boost::detail::numeric_traits<Number>::difference_type
 | 
			
		||||
@@ -358,7 +357,7 @@ void test(Number* = 0)
 | 
			
		||||
        boost::detail::is_signed<Number>::value
 | 
			
		||||
        >::template then<signed_tag, unsigned_tag>::type signedness;
 | 
			
		||||
    
 | 
			
		||||
    test_aux<Number>(signedness());
 | 
			
		||||
    test_aux<Number>(signedness(), 0);
 | 
			
		||||
    std::cout << "passed" << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -374,9 +373,9 @@ int main()
 | 
			
		||||
    test<unsigned int>();
 | 
			
		||||
    test<long>();
 | 
			
		||||
    test<unsigned long>();
 | 
			
		||||
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
 | 
			
		||||
    test<long long>();
 | 
			
		||||
    test<unsigned long long>();
 | 
			
		||||
#if defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_INTEGRAL_INT64_T)
 | 
			
		||||
    test< ::boost::long_long_type>();
 | 
			
		||||
    test< ::boost::ulong_long_type>();
 | 
			
		||||
#elif defined(BOOST_MSVC)
 | 
			
		||||
    // The problem of not having compile-time static class constants other than
 | 
			
		||||
    // enums prevents this from working, since values get truncated.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2917
									
								
								operators.htm
									
									
									
									
									
								
							
							
						
						
									
										2917
									
								
								operators.htm
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,13 +1,14 @@
 | 
			
		||||
//  Demonstrate and test boost/operators.hpp  -------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Beman Dawes 1999. Permission to copy, use, modify, sell and
 | 
			
		||||
//  distribute this software is granted provided this copyright notice appears
 | 
			
		||||
//  in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
//  warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
//  Copyright 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.
 | 
			
		||||
//  See http://www.boost.org/libs/utility for documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  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)
 | 
			
		||||
@@ -184,6 +185,74 @@ namespace
 | 
			
		||||
    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; }
 | 
			
		||||
        bool operator<(const Wrapped5& x) const { return _value < x._value; }
 | 
			
		||||
        bool operator<(U u) const { return _value < u; }
 | 
			
		||||
        bool operator>(U u) const { return _value > u; }
 | 
			
		||||
        bool operator==(const Wrapped5& u) const { return _value == u._value; }
 | 
			
		||||
        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; }
 | 
			
		||||
        bool operator<(const Wrapped6& x) const { return _value < x._value; }
 | 
			
		||||
        bool operator<(U u) const { return _value < u; }
 | 
			
		||||
        bool operator>(U u) const { return _value > u; }
 | 
			
		||||
        bool operator==(const Wrapped6& u) const { return _value == u._value; }
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
@@ -193,20 +262,24 @@ namespace
 | 
			
		||||
 | 
			
		||||
    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_TEST( true_value(y1) == true_value(y2) );
 | 
			
		||||
        BOOST_TEST( true_value(x1) == true_value(x2) );
 | 
			
		||||
        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_TEST( (x1 < y1) == (x2 < y2) );
 | 
			
		||||
        BOOST_TEST( (x1 <= y1) == (x2 <= y2) );
 | 
			
		||||
        BOOST_TEST( (x1 >= y1) == (x2 >= y2) );
 | 
			
		||||
        BOOST_TEST( (x1 > y1) == (x2 > y2) );
 | 
			
		||||
        BOOST_CHECK( (x1 < y1) == (x2 < y2) );
 | 
			
		||||
        BOOST_CHECK( (x1 <= y1) == (x2 <= y2) );
 | 
			
		||||
        BOOST_CHECK( (x1 >= y1) == (x2 >= y2) );
 | 
			
		||||
        BOOST_CHECK( (x1 > y1) == (x2 > y2) );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
@@ -220,8 +293,8 @@ namespace
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 == y1) == (x2 == y2) );
 | 
			
		||||
        BOOST_TEST( (x1 != y1) == (x2 != y2) );
 | 
			
		||||
        BOOST_CHECK( (x1 == y1) == (x2 == y2) );
 | 
			
		||||
        BOOST_CHECK( (x1 != y1) == (x2 != y2) );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
@@ -235,7 +308,7 @@ namespace
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 * y1).value() == (x2 * y2) );
 | 
			
		||||
        BOOST_CHECK( (x1 * y1).value() == (x2 * y2) );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
@@ -245,11 +318,20 @@ namespace
 | 
			
		||||
        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)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 + y1).value() == (x2 + y2) );
 | 
			
		||||
        TEST_OP_R(+);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
@@ -259,12 +341,19 @@ namespace
 | 
			
		||||
        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 );
 | 
			
		||||
        BOOST_TEST( (x1 - y1).value() == (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>
 | 
			
		||||
@@ -272,21 +361,37 @@ namespace
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        if ( y2 != 0 )
 | 
			
		||||
            BOOST_TEST( (x1 / y1).value() == (x2 / y2) );
 | 
			
		||||
            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 )
 | 
			
		||||
            BOOST_TEST( (x1 % y1).value() == (x2 % y2) );
 | 
			
		||||
            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)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 ^ y1).value() == (x2 ^ y2) );
 | 
			
		||||
        TEST_OP_R(^);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
@@ -300,7 +405,7 @@ namespace
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 & y1).value() == (x2 & y2) );
 | 
			
		||||
        TEST_OP_R(&);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
@@ -314,7 +419,7 @@ namespace
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 | y1).value() == (x2 | y2) );
 | 
			
		||||
        TEST_OP_R(|);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
@@ -329,30 +434,30 @@ namespace
 | 
			
		||||
    void test_left_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        BOOST_TEST( (x1 << y1).value() == (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 );
 | 
			
		||||
        BOOST_TEST( (x1 >> y1).value() == (x2 >> y2) );
 | 
			
		||||
        TEST_OP_R(>>);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class X2>
 | 
			
		||||
    void test_incrementable(X1 x1, X2 x2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, x1, x2, x2 );
 | 
			
		||||
        BOOST_TEST( (x1++).value() == x2++ );
 | 
			
		||||
        BOOST_TEST( x1.value() == 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_TEST( (x1--).value() == x2-- );
 | 
			
		||||
        BOOST_TEST( x1.value() == x2 );
 | 
			
		||||
        BOOST_CHECK( (x1--).value() == x2-- );
 | 
			
		||||
        BOOST_CHECK( x1.value() == x2 );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
@@ -374,6 +479,14 @@ namespace
 | 
			
		||||
        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
 | 
			
		||||
    {
 | 
			
		||||
@@ -388,6 +501,18 @@ namespace
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
@@ -427,10 +552,16 @@ 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_TEST( ((e), (t)) )
 | 
			
		||||
 | 
			
		||||
#define PRIVATE_EXPR_TEST(e, t)  BOOST_CHECK( ((e), (t)) )
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
test_main( int , char * [] )
 | 
			
		||||
@@ -445,7 +576,7 @@ test_main( int , char * [] )
 | 
			
		||||
    
 | 
			
		||||
    cout << "Created point, and operated on it." << endl;
 | 
			
		||||
    
 | 
			
		||||
    for (int n = 0; n < 10000; ++n)
 | 
			
		||||
    for (int n = 0; n < 1000; ++n)  // was 10,000 but took too long (Beman)
 | 
			
		||||
    {
 | 
			
		||||
        boost::minstd_rand r;
 | 
			
		||||
        tester<long, int>()(r);
 | 
			
		||||
@@ -459,6 +590,14 @@ test_main( int , char * [] )
 | 
			
		||||
        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;
 | 
			
		||||
@@ -467,22 +606,22 @@ test_main( int , char * [] )
 | 
			
		||||
    MyInt i2(2);
 | 
			
		||||
    MyInt i;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( i1.value() == 1 );
 | 
			
		||||
    BOOST_TEST( i2.value() == 2 );
 | 
			
		||||
    BOOST_TEST( i.value() == 0 );
 | 
			
		||||
    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_TEST( i2 == i );
 | 
			
		||||
    BOOST_TEST( i1 != i2 );
 | 
			
		||||
    BOOST_TEST( i1 <  i2 );
 | 
			
		||||
    BOOST_TEST( i1 <= i2 );
 | 
			
		||||
    BOOST_TEST( i <= i2 );
 | 
			
		||||
    BOOST_TEST( i2 >  i1 );
 | 
			
		||||
    BOOST_TEST( i2 >= i1 );
 | 
			
		||||
    BOOST_TEST( i2 >= i );
 | 
			
		||||
    BOOST_CHECK( i2 == i );
 | 
			
		||||
    BOOST_CHECK( i1 != i2 );
 | 
			
		||||
    BOOST_CHECK( i1 <  i2 );
 | 
			
		||||
    BOOST_CHECK( i1 <= i2 );
 | 
			
		||||
    BOOST_CHECK( i <= i2 );
 | 
			
		||||
    BOOST_CHECK( i2 >  i1 );
 | 
			
		||||
    BOOST_CHECK( i2 >= i1 );
 | 
			
		||||
    BOOST_CHECK( i2 >= i );
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
 | 
			
		||||
@@ -499,93 +638,93 @@ test_main( int , char * [] )
 | 
			
		||||
 | 
			
		||||
    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_TEST( j1.value() == 1 );
 | 
			
		||||
    BOOST_TEST( j2.value() == 2 );
 | 
			
		||||
    BOOST_TEST( j.value() == 0 );
 | 
			
		||||
    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_TEST( j2 == j );
 | 
			
		||||
    BOOST_TEST( 2 == j );
 | 
			
		||||
    BOOST_TEST( j2 == 2 );    
 | 
			
		||||
    BOOST_TEST( j == j2 );
 | 
			
		||||
    BOOST_TEST( j1 != j2 );
 | 
			
		||||
    BOOST_TEST( j1 != 2 );
 | 
			
		||||
    BOOST_TEST( 1 != j2 );
 | 
			
		||||
    BOOST_TEST( j1 <  j2 );
 | 
			
		||||
    BOOST_TEST( 1 <  j2 );
 | 
			
		||||
    BOOST_TEST( j1 <  2 );
 | 
			
		||||
    BOOST_TEST( j1 <= j2 );
 | 
			
		||||
    BOOST_TEST( 1 <= j2 );
 | 
			
		||||
    BOOST_TEST( j1 <= j );
 | 
			
		||||
    BOOST_TEST( j <= j2 );
 | 
			
		||||
    BOOST_TEST( 2 <= j2 );
 | 
			
		||||
    BOOST_TEST( j <= 2 );
 | 
			
		||||
    BOOST_TEST( j2 >  j1 );
 | 
			
		||||
    BOOST_TEST( 2 >  j1 );
 | 
			
		||||
    BOOST_TEST( j2 >  1 );
 | 
			
		||||
    BOOST_TEST( j2 >= j1 );
 | 
			
		||||
    BOOST_TEST( 2 >= j1 );
 | 
			
		||||
    BOOST_TEST( j2 >= 1 );
 | 
			
		||||
    BOOST_TEST( j2 >= j );
 | 
			
		||||
    BOOST_TEST( 2 >= j );
 | 
			
		||||
    BOOST_TEST( j2 >= 2 );
 | 
			
		||||
    BOOST_CHECK( j2 == j );
 | 
			
		||||
    BOOST_CHECK( 2 == j );
 | 
			
		||||
    BOOST_CHECK( j2 == 2 );    
 | 
			
		||||
    BOOST_CHECK( j == j2 );
 | 
			
		||||
    BOOST_CHECK( j1 != j2 );
 | 
			
		||||
    BOOST_CHECK( j1 != 2 );
 | 
			
		||||
    BOOST_CHECK( 1 != j2 );
 | 
			
		||||
    BOOST_CHECK( j1 <  j2 );
 | 
			
		||||
    BOOST_CHECK( 1 <  j2 );
 | 
			
		||||
    BOOST_CHECK( j1 <  2 );
 | 
			
		||||
    BOOST_CHECK( j1 <= j2 );
 | 
			
		||||
    BOOST_CHECK( 1 <= j2 );
 | 
			
		||||
    BOOST_CHECK( j1 <= j );
 | 
			
		||||
    BOOST_CHECK( j <= j2 );
 | 
			
		||||
    BOOST_CHECK( 2 <= j2 );
 | 
			
		||||
    BOOST_CHECK( j <= 2 );
 | 
			
		||||
    BOOST_CHECK( j2 >  j1 );
 | 
			
		||||
    BOOST_CHECK( 2 >  j1 );
 | 
			
		||||
    BOOST_CHECK( j2 >  1 );
 | 
			
		||||
    BOOST_CHECK( j2 >= j1 );
 | 
			
		||||
    BOOST_CHECK( 2 >= j1 );
 | 
			
		||||
    BOOST_CHECK( j2 >= 1 );
 | 
			
		||||
    BOOST_CHECK( j2 >= j );
 | 
			
		||||
    BOOST_CHECK( 2 >= j );
 | 
			
		||||
    BOOST_CHECK( j2 >= 2 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( (j1 + 2) == 3 );
 | 
			
		||||
    BOOST_TEST( (1 + j2) == 3 );
 | 
			
		||||
    BOOST_CHECK( (j1 + 2) == 3 );
 | 
			
		||||
    BOOST_CHECK( (1 + j2) == 3 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j + 2) == 5 );
 | 
			
		||||
    BOOST_TEST( (3 + j2) == 5 );
 | 
			
		||||
    BOOST_CHECK( (j + 2) == 5 );
 | 
			
		||||
    BOOST_CHECK( (3 + j2) == 5 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j - 1) == 4 );
 | 
			
		||||
    BOOST_CHECK( (j - 1) == 4 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j * 2) == 8 );
 | 
			
		||||
    BOOST_TEST( (4 * j2) == 8 );
 | 
			
		||||
    BOOST_CHECK( (j * 2) == 8 );
 | 
			
		||||
    BOOST_CHECK( (4 * j2) == 8 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j / 2) == 4 );
 | 
			
		||||
    BOOST_CHECK( (j / 2) == 4 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j % 3) == 1 );
 | 
			
		||||
    BOOST_CHECK( (j % 3) == 1 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (1 | j2 | j) == 7 );
 | 
			
		||||
    BOOST_TEST( (j1 | 2 | j) == 7 );
 | 
			
		||||
    BOOST_TEST( (j1 | j2 | 4) == 7 );
 | 
			
		||||
    BOOST_CHECK( (1 | j2 | j) == 7 );
 | 
			
		||||
    BOOST_CHECK( (j1 | 2 | j) == 7 );
 | 
			
		||||
    BOOST_CHECK( (j1 | j2 | 4) == 7 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (7 & j2) == 2 );
 | 
			
		||||
    BOOST_TEST( (j & 2) == 2 );
 | 
			
		||||
    BOOST_CHECK( (7 & j2) == 2 );
 | 
			
		||||
    BOOST_CHECK( (j & 2) == 2 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (3 ^ j1) == 2 );
 | 
			
		||||
    BOOST_TEST( (j ^ 1) == 2 );
 | 
			
		||||
    BOOST_CHECK( (3 ^ j1) == 2 );
 | 
			
		||||
    BOOST_CHECK( (j ^ 1) == 2 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( (j1 << 2) == 4 );
 | 
			
		||||
    BOOST_TEST( (j2 << 1) == 4 );
 | 
			
		||||
    BOOST_CHECK( (j1 << 2) == 4 );
 | 
			
		||||
    BOOST_CHECK( (j2 << 1) == 4 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( (j >> 2) == 1 );
 | 
			
		||||
    BOOST_TEST( (j2 >> 1) == 1 );
 | 
			
		||||
    BOOST_CHECK( (j >> 2) == 1 );
 | 
			
		||||
    BOOST_CHECK( (j2 >> 1) == 1 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyLong objects.\n";
 | 
			
		||||
@@ -594,22 +733,22 @@ test_main( int , char * [] )
 | 
			
		||||
    MyChar k2(2);
 | 
			
		||||
    MyChar k;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( k1.value() == 1 );
 | 
			
		||||
    BOOST_TEST( k2.value() == 2 );
 | 
			
		||||
    BOOST_TEST( k.value() == 0 );
 | 
			
		||||
    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_TEST( k2 == k );
 | 
			
		||||
    BOOST_TEST( k1 != k2 );
 | 
			
		||||
    BOOST_TEST( k1 <  k2 );
 | 
			
		||||
    BOOST_TEST( k1 <= k2 );
 | 
			
		||||
    BOOST_TEST( k <= k2 );
 | 
			
		||||
    BOOST_TEST( k2 >  k1 );
 | 
			
		||||
    BOOST_TEST( k2 >= k1 );
 | 
			
		||||
    BOOST_TEST( k2 >= k );
 | 
			
		||||
    BOOST_CHECK( k2 == k );
 | 
			
		||||
    BOOST_CHECK( k1 != k2 );
 | 
			
		||||
    BOOST_CHECK( k1 <  k2 );
 | 
			
		||||
    BOOST_CHECK( k1 <= k2 );
 | 
			
		||||
    BOOST_CHECK( k <= k2 );
 | 
			
		||||
    BOOST_CHECK( k2 >  k1 );
 | 
			
		||||
    BOOST_CHECK( k2 >= k1 );
 | 
			
		||||
    BOOST_CHECK( k2 >= k );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyChar objects.\n";
 | 
			
		||||
 | 
			
		||||
@@ -617,41 +756,142 @@ test_main( int , char * [] )
 | 
			
		||||
    MyShort l2(2);
 | 
			
		||||
    MyShort l;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( l1.value() == 1 );
 | 
			
		||||
    BOOST_TEST( l2.value() == 2 );
 | 
			
		||||
    BOOST_TEST( l.value() == 0 );
 | 
			
		||||
    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_TEST( l2 == l );
 | 
			
		||||
    BOOST_TEST( 2 == l );
 | 
			
		||||
    BOOST_TEST( l2 == 2 );    
 | 
			
		||||
    BOOST_TEST( l == l2 );
 | 
			
		||||
    BOOST_TEST( l1 != l2 );
 | 
			
		||||
    BOOST_TEST( l1 != 2 );
 | 
			
		||||
    BOOST_TEST( 1 != l2 );
 | 
			
		||||
    BOOST_TEST( l1 <  l2 );
 | 
			
		||||
    BOOST_TEST( 1 <  l2 );
 | 
			
		||||
    BOOST_TEST( l1 <  2 );
 | 
			
		||||
    BOOST_TEST( l1 <= l2 );
 | 
			
		||||
    BOOST_TEST( 1 <= l2 );
 | 
			
		||||
    BOOST_TEST( l1 <= l );
 | 
			
		||||
    BOOST_TEST( l <= l2 );
 | 
			
		||||
    BOOST_TEST( 2 <= l2 );
 | 
			
		||||
    BOOST_TEST( l <= 2 );
 | 
			
		||||
    BOOST_TEST( l2 >  l1 );
 | 
			
		||||
    BOOST_TEST( 2 >  l1 );
 | 
			
		||||
    BOOST_TEST( l2 >  1 );
 | 
			
		||||
    BOOST_TEST( l2 >= l1 );
 | 
			
		||||
    BOOST_TEST( 2 >= l1 );
 | 
			
		||||
    BOOST_TEST( l2 >= 1 );
 | 
			
		||||
    BOOST_TEST( l2 >= l );
 | 
			
		||||
    BOOST_TEST( 2 >= l );
 | 
			
		||||
    BOOST_TEST( l2 >= 2 );
 | 
			
		||||
    BOOST_CHECK( l2 == l );
 | 
			
		||||
    BOOST_CHECK( 2 == l );
 | 
			
		||||
    BOOST_CHECK( l2 == 2 );    
 | 
			
		||||
    BOOST_CHECK( l == l2 );
 | 
			
		||||
    BOOST_CHECK( l1 != l2 );
 | 
			
		||||
    BOOST_CHECK( l1 != 2 );
 | 
			
		||||
    BOOST_CHECK( 1 != l2 );
 | 
			
		||||
    BOOST_CHECK( l1 <  l2 );
 | 
			
		||||
    BOOST_CHECK( 1 <  l2 );
 | 
			
		||||
    BOOST_CHECK( l1 <  2 );
 | 
			
		||||
    BOOST_CHECK( l1 <= l2 );
 | 
			
		||||
    BOOST_CHECK( 1 <= l2 );
 | 
			
		||||
    BOOST_CHECK( l1 <= l );
 | 
			
		||||
    BOOST_CHECK( l <= l2 );
 | 
			
		||||
    BOOST_CHECK( 2 <= l2 );
 | 
			
		||||
    BOOST_CHECK( l <= 2 );
 | 
			
		||||
    BOOST_CHECK( l2 >  l1 );
 | 
			
		||||
    BOOST_CHECK( 2 >  l1 );
 | 
			
		||||
    BOOST_CHECK( l2 >  1 );
 | 
			
		||||
    BOOST_CHECK( l2 >= l1 );
 | 
			
		||||
    BOOST_CHECK( 2 >= l1 );
 | 
			
		||||
    BOOST_CHECK( l2 >= 1 );
 | 
			
		||||
    BOOST_CHECK( l2 >= l );
 | 
			
		||||
    BOOST_CHECK( 2 >= l );
 | 
			
		||||
    BOOST_CHECK( 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( di2 == di );
 | 
			
		||||
    BOOST_CHECK( 2 == di );
 | 
			
		||||
    BOOST_CHECK( di == 2 );
 | 
			
		||||
    BOOST_CHECK( di1 < di2 );
 | 
			
		||||
    BOOST_CHECK( 1 < di2 );
 | 
			
		||||
    BOOST_CHECK( di1 <= di2 );
 | 
			
		||||
    BOOST_CHECK( 1 <= di2 );
 | 
			
		||||
    BOOST_CHECK( di2 > di1 );
 | 
			
		||||
    BOOST_CHECK( di2 > 1 );
 | 
			
		||||
    BOOST_CHECK( di2 >= di1 );
 | 
			
		||||
    BOOST_CHECK( di2 >= 1 );
 | 
			
		||||
    BOOST_CHECK( di1 / di2 == half );
 | 
			
		||||
    BOOST_CHECK( di1 / 2 == half );
 | 
			
		||||
    BOOST_CHECK( 1 / di2 == half );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=2) == half) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=di2) == half) );
 | 
			
		||||
    BOOST_CHECK( di1 * di2 == di2 );
 | 
			
		||||
    BOOST_CHECK( di1 * 2 == di2 );
 | 
			
		||||
    BOOST_CHECK( 1 * di2 == di2 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=2) == di2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=di2) == di2) );
 | 
			
		||||
    BOOST_CHECK( di2 - di1 == di1 );
 | 
			
		||||
    BOOST_CHECK( di2 - 1 == di1 );
 | 
			
		||||
    BOOST_CHECK( 2 - di1 == di1 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=1) == di1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=di1) == di1) );
 | 
			
		||||
    BOOST_CHECK( di1 + di1 == di2 );
 | 
			
		||||
    BOOST_CHECK( di1 + 1 == di2 );
 | 
			
		||||
    BOOST_CHECK( 1 + di1 == di2 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=1) == di2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp=di1), ((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( li2 == li );
 | 
			
		||||
    BOOST_CHECK( 2 == li );
 | 
			
		||||
    BOOST_CHECK( li == 2 );
 | 
			
		||||
    BOOST_CHECK( li1 < li2 );
 | 
			
		||||
    BOOST_CHECK( 1 < li2 );
 | 
			
		||||
    BOOST_CHECK( li1 <= li2 );
 | 
			
		||||
    BOOST_CHECK( 1 <= li2 );
 | 
			
		||||
    BOOST_CHECK( li2 > li1 );
 | 
			
		||||
    BOOST_CHECK( li2 > 1 );
 | 
			
		||||
    BOOST_CHECK( li2 >= li1 );
 | 
			
		||||
    BOOST_CHECK( li2 >= 1 );
 | 
			
		||||
    BOOST_CHECK( li1 % li2 == li1 );
 | 
			
		||||
    BOOST_CHECK( li1 % 2 == li1 );
 | 
			
		||||
    BOOST_CHECK( 1 % li2 == li1 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=2) == li1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=li2) == li1) );
 | 
			
		||||
    BOOST_CHECK( li1 / li2 == 0 );
 | 
			
		||||
    BOOST_CHECK( li1 / 2 == 0 );
 | 
			
		||||
    BOOST_CHECK( 1 / li2 == 0 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=2) == 0) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=li2) == 0) );
 | 
			
		||||
    BOOST_CHECK( li1 * li2 == li2 );
 | 
			
		||||
    BOOST_CHECK( li1 * 2 == li2 );
 | 
			
		||||
    BOOST_CHECK( 1 * li2 == li2 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=2) == li2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=li2) == li2) );
 | 
			
		||||
    BOOST_CHECK( li2 - li1 == li1 );
 | 
			
		||||
    BOOST_CHECK( li2 - 1 == li1 );
 | 
			
		||||
    BOOST_CHECK( 2 - li1 == li1 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=1) == li1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=li1) == li1) );
 | 
			
		||||
    BOOST_CHECK( li1 + li1 == li2 );
 | 
			
		||||
    BOOST_CHECK( li1 + 1 == li2 );
 | 
			
		||||
    BOOST_CHECK( 1 + li1 == li2 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=1) == li2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=li1) == li2) );
 | 
			
		||||
 | 
			
		||||
    cout << "Performed tests on MyLongInt objects.\n";
 | 
			
		||||
 | 
			
		||||
    return boost::exit_success;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,391 +0,0 @@
 | 
			
		||||
<html>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 | 
			
		||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
<meta name="ProgId" content="FrontPage.Editor.Document">
 | 
			
		||||
<title>Projection Iterator Adaptor Documentation</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
 | 
			
		||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
 | 
			
		||||
align="center" width="277" height="86">
 | 
			
		||||
 | 
			
		||||
<h1>Projection Iterator Adaptor</h1>
 | 
			
		||||
 | 
			
		||||
Defined in header
 | 
			
		||||
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The projection iterator adaptor is similar to the <a
 | 
			
		||||
href="./transform_iterator.htm">transform iterator adaptor</a> in that
 | 
			
		||||
its <tt>operator*()</tt> applies some function to the result of
 | 
			
		||||
dereferencing the base iterator and then returns the result. The
 | 
			
		||||
difference is that the function must return a reference to some
 | 
			
		||||
existing object (for example, a data member within the
 | 
			
		||||
<tt>value_type</tt> of the base iterator). The following
 | 
			
		||||
<b>pseudo-code</b> gives the basic idea. The data member <tt>p</tt> is
 | 
			
		||||
the function object.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
  reference projection_iterator::operator*() const {
 | 
			
		||||
    return this->p(*this->base_iterator);
 | 
			
		||||
  }
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h2>Synopsis</h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
 | 
			
		||||
  struct projection_iterator_generator;
 | 
			
		||||
  
 | 
			
		||||
  template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, 
 | 
			
		||||
            class BaseIterator, class ConstBaseIterator>
 | 
			
		||||
  struct projection_iterator_pair_generator;
 | 
			
		||||
 | 
			
		||||
  template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
 | 
			
		||||
  typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type
 | 
			
		||||
  make_projection_iterator(BaseIterator base,
 | 
			
		||||
			   const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
 | 
			
		||||
 | 
			
		||||
  template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class ConstBaseIterator>
 | 
			
		||||
  typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type
 | 
			
		||||
  make_const_projection_iterator(ConstBaseIterator base,
 | 
			
		||||
                                 const AdaptableUnaryFunction& p = AdaptableUnaryFunction())  
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<h2><a name="projection_iterator_generator">The Projection Iterator Type
 | 
			
		||||
Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
The class <tt>projection_iterator_generator</tt> is a helper class
 | 
			
		||||
whose purpose is to construct an projection iterator type.  The main
 | 
			
		||||
template parameter for this class is the <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a>
 | 
			
		||||
function object type and the <tt>BaseIterator</tt> type that is being
 | 
			
		||||
wrapped.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
 | 
			
		||||
class projection_iterator_generator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting projection iterator type 
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
In the following example we have a list of personnel records. Each
 | 
			
		||||
record has an employee's name and ID number. We want to be able to
 | 
			
		||||
traverse through the list accessing either the name or the ID numbers
 | 
			
		||||
of the employees using the projection iterator so we create the
 | 
			
		||||
function object classes <tt>select_name</tt> and
 | 
			
		||||
<tt>select_ID</tt>. We then use the
 | 
			
		||||
<tt>projection_iterator_generator</tt> class to create a projection
 | 
			
		||||
iterator and use it to print out the names of the employees.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
struct personnel_record {
 | 
			
		||||
  personnel_record(std::string n, int id) : m_name(n), m_ID(id) { }
 | 
			
		||||
  std::string m_name;
 | 
			
		||||
  int m_ID;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct select_name {
 | 
			
		||||
  typedef personnel_record argument_type;
 | 
			
		||||
  typedef std::string result_type;
 | 
			
		||||
  const std::string& operator()(const personnel_record& r) const {
 | 
			
		||||
    return r.m_name;
 | 
			
		||||
  }
 | 
			
		||||
  std::string& operator()(personnel_record& r) const {
 | 
			
		||||
    return r.m_name;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct select_ID {
 | 
			
		||||
  typedef personnel_record argument_type;
 | 
			
		||||
  typedef int result_type;
 | 
			
		||||
  const int& operator()(const personnel_record& r) const {
 | 
			
		||||
    return r.m_ID;
 | 
			
		||||
  }
 | 
			
		||||
  int& operator()(personnel_record& r) const {
 | 
			
		||||
    return r.m_ID;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  std::list<personnel_record> personnel_list;
 | 
			
		||||
 | 
			
		||||
  personnel_list.push_back(personnel_record("Barney", 13423));
 | 
			
		||||
  personnel_list.push_back(personnel_record("Fred", 12343));
 | 
			
		||||
  personnel_list.push_back(personnel_record("Wilma", 62454));
 | 
			
		||||
  personnel_list.push_back(personnel_record("Betty", 20490));
 | 
			
		||||
 | 
			
		||||
  // Example of using projection_iterator_generator
 | 
			
		||||
  // to print out the names in the personnel list.
 | 
			
		||||
 | 
			
		||||
  boost::projection_iterator_generator<select_name,
 | 
			
		||||
    std::list<personnel_record>::iterator>::type
 | 
			
		||||
    personnel_first(personnel_list.begin()),
 | 
			
		||||
    personnel_last(personnel_list.end());
 | 
			
		||||
 | 
			
		||||
  std::copy(personnel_first, personnel_last,
 | 
			
		||||
            std::ostream_iterator<std::string>(std::cout, "\n"));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // to be continued...
 | 
			
		||||
</pre>
 | 
			
		||||
The output for this part is:
 | 
			
		||||
<pre>
 | 
			
		||||
Barney
 | 
			
		||||
Fred
 | 
			
		||||
Wilma
 | 
			
		||||
Betty
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
<Table border>
 | 
			
		||||
<TR>
 | 
			
		||||
<TH>Parameter</TH><TH>Description</TH>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD>
 | 
			
		||||
<TD>The type of the function object. The <tt>argument_type</tt> of the
 | 
			
		||||
function must match the value type of the base iterator. The function
 | 
			
		||||
should return a reference to the function's <tt>result_type</tt>.
 | 
			
		||||
The <tt>result_type</tt> will be the resulting iterator's <tt>value_type</tt>.
 | 
			
		||||
</TD>
 | 
			
		||||
</TD>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>BaseIterator</tt></TD>
 | 
			
		||||
<TD>The iterator type being wrapped.</TD>
 | 
			
		||||
</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
</Table>
 | 
			
		||||
 | 
			
		||||
<h3>Model of</h3>
 | 
			
		||||
 | 
			
		||||
If the base iterator is a model of <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
Access Iterator</a> then so is the resulting projection iterator.  If
 | 
			
		||||
the base iterator supports less functionality than this the resulting
 | 
			
		||||
projection iterator will also support less functionality.
 | 
			
		||||
 | 
			
		||||
<h3>Members</h3>
 | 
			
		||||
 | 
			
		||||
The projection iterator type implements the member functions and
 | 
			
		||||
operators required of the <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
Access Iterator</a> concept.
 | 
			
		||||
In addition it has the following constructor:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
projection_iterator_generator::type(const BaseIterator& it,
 | 
			
		||||
                                    const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
<h2><a name="projection_iterator_pair_generator">The Projection Iterator Pair
 | 
			
		||||
Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
Sometimes a mutable/const pair of iterator types is needed, such as
 | 
			
		||||
when implementing a container type. The
 | 
			
		||||
<tt>projection_iterator_pair_generator</tt> class makes it more
 | 
			
		||||
convenient to create this pair of iterator types.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator, class ConstBaseIterator>
 | 
			
		||||
class projection_iterator_pair_generator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> iterator;       // the mutable projection iterator type 
 | 
			
		||||
  typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> const_iterator; // the immutable projection iterator type 
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
In this part of the example we use the
 | 
			
		||||
<tt>projection_iterator_pair_generator</tt> to create a mutable/const
 | 
			
		||||
pair of projection iterators that access the ID numbers of the
 | 
			
		||||
personnel. We use the mutable iterator to re-index the ID numbers from
 | 
			
		||||
zero. We then use the constant iterator to print the ID numbers out.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
  // continuing from the last example...
 | 
			
		||||
 | 
			
		||||
  typedef boost::projection_iterator_pair_generator<select_ID,
 | 
			
		||||
    std::list<personnel_record>::iterator,
 | 
			
		||||
    std::list<personnel_record>::const_iterator> PairGen;
 | 
			
		||||
 | 
			
		||||
  PairGen::iterator ID_first(personnel_list.begin()),
 | 
			
		||||
    ID_last(personnel_list.end());
 | 
			
		||||
 | 
			
		||||
  int new_id = 0;
 | 
			
		||||
  while (ID_first != ID_last) {
 | 
			
		||||
    *ID_first = new_id++;
 | 
			
		||||
    ++ID_first;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  PairGen::const_iterator const_ID_first(personnel_list.begin()),
 | 
			
		||||
    const_ID_last(personnel_list.end());
 | 
			
		||||
 | 
			
		||||
  std::copy(const_ID_first, const_ID_last,
 | 
			
		||||
            std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  
 | 
			
		||||
  // to be continued...
 | 
			
		||||
</pre>
 | 
			
		||||
The output is:
 | 
			
		||||
<pre>
 | 
			
		||||
0 1 2 3 
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
<Table border>
 | 
			
		||||
<TR>
 | 
			
		||||
<TH>Parameter</TH><TH>Description</TH>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD>
 | 
			
		||||
<TD>The type of the function object. The <tt>argument_type</tt> of the
 | 
			
		||||
function must match the value type of the base iterator. The function
 | 
			
		||||
should return a true reference to the function's <tt>result_type</tt>.
 | 
			
		||||
The <tt>result_type</tt> will be the resulting iterator's <tt>value_type</tt>.
 | 
			
		||||
</TD>
 | 
			
		||||
</TD>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>BaseIterator</tt></TD>
 | 
			
		||||
<TD>The mutable iterator type being wrapped.</TD>
 | 
			
		||||
</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><tt>ConstBaseIterator</tt></TD>
 | 
			
		||||
<TD>The constant iterator type being wrapped.</TD>
 | 
			
		||||
</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
</Table>
 | 
			
		||||
 | 
			
		||||
<h3>Model of</h3>
 | 
			
		||||
 | 
			
		||||
If the base iterator types model the <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
Access Iterator</a> then so do the resulting projection iterator
 | 
			
		||||
types.  If the base iterators support less functionality the
 | 
			
		||||
resulting projection iterator types will also support less
 | 
			
		||||
functionality.  The resulting <tt>iterator</tt> type is mutable, and
 | 
			
		||||
the resulting <tt>const_iterator</tt> type is constant.
 | 
			
		||||
 | 
			
		||||
<h3>Members</h3>
 | 
			
		||||
 | 
			
		||||
The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types
 | 
			
		||||
implements the member functions and operators required of the <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
 | 
			
		||||
Access Iterator</a> concept.  In addition they support the following
 | 
			
		||||
constructors:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
projection_iterator_pair_generator::iterator(const BaseIterator& it,
 | 
			
		||||
                                             const AdaptableUnaryFunction& p = AdaptableUnaryFunction())</pre>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
projection_iterator_pair_generator::const_iterator(const BaseIterator& it,
 | 
			
		||||
                                                   const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
<h2><a name="make_projection_iterator">The Projection Iterator Object Generators</a></h2>
 | 
			
		||||
 | 
			
		||||
The <tt>make_projection_iterator()</tt> and
 | 
			
		||||
<tt>make_const_projection_iterator()</tt> functions provide a more
 | 
			
		||||
convenient way to create projection iterator objects. The functions
 | 
			
		||||
save the user the trouble of explicitly writing out the iterator
 | 
			
		||||
types.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
 | 
			
		||||
typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type
 | 
			
		||||
make_projection_iterator(BaseIterator base,
 | 
			
		||||
			 const AdaptableUnaryFunction& p = AdaptableUnaryFunction())  
 | 
			
		||||
 | 
			
		||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class ConstBaseIterator>
 | 
			
		||||
typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type
 | 
			
		||||
make_const_projection_iterator(ConstBaseIterator base,
 | 
			
		||||
			       const AdaptableUnaryFunction& p = AdaptableUnaryFunction())  
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
In this part of the example, we again print out the names of the
 | 
			
		||||
personnel, but this time we use the
 | 
			
		||||
<tt>make_const_projection_iterator()</tt> function to save some typing.
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
  // continuing from the last example...
 | 
			
		||||
 | 
			
		||||
  std::copy
 | 
			
		||||
    (boost::make_const_projection_iterator<select_name>(personnel_list.begin()),
 | 
			
		||||
     boost::make_const_projection_iterator<select_name>(personnel_list.end()),
 | 
			
		||||
     std::ostream_iterator<std::string>(std::cout, "\n"));
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
The output is:
 | 
			
		||||
<pre>
 | 
			
		||||
Barney
 | 
			
		||||
Fred
 | 
			
		||||
Wilma
 | 
			
		||||
Betty
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->08 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14892" --></p>
 | 
			
		||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
 | 
			
		||||
modify, sell and distribute this document is granted provided this copyright
 | 
			
		||||
notice appears in all copies. This document is provided "as is"
 | 
			
		||||
without express or implied warranty, and with no claim as to its suitability for
 | 
			
		||||
any purpose.</p>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
<!--  LocalWords:  html charset alt gif hpp BaseIterator const namespace struct
 | 
			
		||||
 -->
 | 
			
		||||
<!--  LocalWords:  ConstPointer ConstReference typename iostream int abcdefg
 | 
			
		||||
 -->
 | 
			
		||||
<!--  LocalWords:  sizeof  PairGen pre Siek htm AdaptableUnaryFunction
 | 
			
		||||
 -->
 | 
			
		||||
<!--  LocalWords:  ConstBaseIterator
 | 
			
		||||
 -->
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
 | 
			
		||||
// distribute this software is granted provided this copyright notice appears
 | 
			
		||||
// in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
// warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
struct personnel_record {
 | 
			
		||||
  personnel_record(std::string n, int id) : m_name(n), m_ID(id) { }
 | 
			
		||||
  std::string m_name;
 | 
			
		||||
  int m_ID;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct select_name {
 | 
			
		||||
  typedef personnel_record argument_type;
 | 
			
		||||
  typedef std::string result_type;
 | 
			
		||||
  const std::string& operator()(const personnel_record& r) const {
 | 
			
		||||
    return r.m_name;
 | 
			
		||||
  }
 | 
			
		||||
  std::string& operator()(personnel_record& r) const {
 | 
			
		||||
    return r.m_name;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct select_ID {
 | 
			
		||||
  typedef personnel_record argument_type;
 | 
			
		||||
  typedef int result_type;
 | 
			
		||||
  const int& operator()(const personnel_record& r) const {
 | 
			
		||||
    return r.m_ID;
 | 
			
		||||
  }
 | 
			
		||||
  int& operator()(personnel_record& r) const {
 | 
			
		||||
    return r.m_ID;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  std::list<personnel_record> personnel_list;
 | 
			
		||||
 | 
			
		||||
  personnel_list.push_back(personnel_record("Barney", 13423));
 | 
			
		||||
  personnel_list.push_back(personnel_record("Fred", 12343));
 | 
			
		||||
  personnel_list.push_back(personnel_record("Wilma", 62454));
 | 
			
		||||
  personnel_list.push_back(personnel_record("Betty", 20490));
 | 
			
		||||
 | 
			
		||||
  // Example of using projection_iterator_generator
 | 
			
		||||
  // to print out the names in the personnel list.
 | 
			
		||||
 | 
			
		||||
  boost::projection_iterator_generator<select_name,
 | 
			
		||||
    std::list<personnel_record>::iterator>::type
 | 
			
		||||
    personnel_first(personnel_list.begin()),
 | 
			
		||||
    personnel_last(personnel_list.end());
 | 
			
		||||
 | 
			
		||||
  std::copy(personnel_first, personnel_last,
 | 
			
		||||
            std::ostream_iterator<std::string>(std::cout, "\n"));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  
 | 
			
		||||
  // Example of using projection_iterator_pair_generator
 | 
			
		||||
  // to assign new ID numbers to the personnel.
 | 
			
		||||
  
 | 
			
		||||
  typedef boost::projection_iterator_pair_generator<select_ID,
 | 
			
		||||
    std::list<personnel_record>::iterator,
 | 
			
		||||
    std::list<personnel_record>::const_iterator> PairGen;
 | 
			
		||||
 | 
			
		||||
  PairGen::iterator ID_first(personnel_list.begin()),
 | 
			
		||||
    ID_last(personnel_list.end());
 | 
			
		||||
 | 
			
		||||
  int new_id = 0;
 | 
			
		||||
  while (ID_first != ID_last) {
 | 
			
		||||
    *ID_first = new_id++;
 | 
			
		||||
    ++ID_first;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  PairGen::const_iterator const_ID_first(personnel_list.begin()),
 | 
			
		||||
    const_ID_last(personnel_list.end());
 | 
			
		||||
 | 
			
		||||
  std::copy(const_ID_first, const_ID_last,
 | 
			
		||||
            std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  
 | 
			
		||||
  // Example of using make_const_projection_iterator()
 | 
			
		||||
  // to print out the names in the personnel list again.
 | 
			
		||||
  
 | 
			
		||||
  std::copy
 | 
			
		||||
    (boost::make_const_projection_iterator<select_name>(personnel_list.begin()),
 | 
			
		||||
     boost::make_const_projection_iterator<select_name>(personnel_list.end()),
 | 
			
		||||
     std::ostream_iterator<std::string>(std::cout, "\n"));
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										134
									
								
								ref_ct_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								ref_ct_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
// Copyright David Abrahams and Aleksey Gurtovoy
 | 
			
		||||
// 2002-2004. Distributed under the Boost Software License, Version
 | 
			
		||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
// compile-time test for "boost/ref.hpp" header content
 | 
			
		||||
// see 'ref_test.cpp' for run-time part
 | 
			
		||||
 | 
			
		||||
#include <boost/ref.hpp>
 | 
			
		||||
#include <boost/type_traits/is_same.hpp>
 | 
			
		||||
#include <boost/type_traits/remove_const.hpp>
 | 
			
		||||
#include <boost/static_assert.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/mpl/assert.hpp>
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
template< typename T, typename U >
 | 
			
		||||
void ref_test(boost::reference_wrapper<U>)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename boost::reference_wrapper<U>::type type;
 | 
			
		||||
    BOOST_STATIC_ASSERT((boost::is_same<U,type>::value));
 | 
			
		||||
    BOOST_STATIC_ASSERT((boost::is_same<T,type>::value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< typename T >
 | 
			
		||||
void assignable_test(T x)
 | 
			
		||||
{
 | 
			
		||||
    x = x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< bool R, typename T >
 | 
			
		||||
void is_reference_wrapper_test(T)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_ASSERT(boost::is_reference_wrapper<T>::value == R);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< typename R, typename Ref >
 | 
			
		||||
void cxx_reference_test(Ref)
 | 
			
		||||
{
 | 
			
		||||
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
 | 
			
		||||
    typedef typename boost::remove_const<Ref>::type ref;
 | 
			
		||||
    BOOST_STATIC_ASSERT((boost::is_same<R,ref>::value));
 | 
			
		||||
#else
 | 
			
		||||
    BOOST_STATIC_ASSERT((boost::is_same<R,Ref>::value));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< typename R, typename Ref >
 | 
			
		||||
void unwrap_reference_test(Ref)
 | 
			
		||||
{
 | 
			
		||||
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
 | 
			
		||||
    typedef typename boost::remove_const<Ref>::type ref;
 | 
			
		||||
    typedef typename boost::unwrap_reference<ref>::type type;
 | 
			
		||||
#else
 | 
			
		||||
    typedef typename boost::unwrap_reference<Ref>::type type;
 | 
			
		||||
#endif
 | 
			
		||||
    BOOST_STATIC_ASSERT((boost::is_same<R,type>::value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    int& ri = i;
 | 
			
		||||
 | 
			
		||||
    int const ci = 0;
 | 
			
		||||
    int const& rci = ci;
 | 
			
		||||
 | 
			
		||||
    // 'ref/cref' functions test
 | 
			
		||||
    ref_test<int>(boost::ref(i));
 | 
			
		||||
    ref_test<int>(boost::ref(ri));
 | 
			
		||||
    ref_test<int const>(boost::ref(ci));
 | 
			
		||||
    ref_test<int const>(boost::ref(rci));
 | 
			
		||||
 | 
			
		||||
    ref_test<int const>(boost::cref(i));
 | 
			
		||||
    ref_test<int const>(boost::cref(ri));
 | 
			
		||||
    ref_test<int const>(boost::cref(ci));
 | 
			
		||||
    ref_test<int const>(boost::cref(rci));
 | 
			
		||||
 | 
			
		||||
    // test 'assignable' requirement
 | 
			
		||||
    assignable_test(boost::ref(i));
 | 
			
		||||
    assignable_test(boost::ref(ri));
 | 
			
		||||
    assignable_test(boost::cref(i));
 | 
			
		||||
    assignable_test(boost::cref(ci));
 | 
			
		||||
    assignable_test(boost::cref(rci));
 | 
			
		||||
 | 
			
		||||
    // 'is_reference_wrapper' test
 | 
			
		||||
    is_reference_wrapper_test<true>(boost::ref(i));
 | 
			
		||||
    is_reference_wrapper_test<true>(boost::ref(ri));
 | 
			
		||||
    is_reference_wrapper_test<true>(boost::cref(i));
 | 
			
		||||
    is_reference_wrapper_test<true>(boost::cref(ci));
 | 
			
		||||
    is_reference_wrapper_test<true>(boost::cref(rci));
 | 
			
		||||
 | 
			
		||||
    is_reference_wrapper_test<false>(i);
 | 
			
		||||
    is_reference_wrapper_test<false, int&>(ri);
 | 
			
		||||
    is_reference_wrapper_test<false>(ci);
 | 
			
		||||
    is_reference_wrapper_test<false, int const&>(rci);
 | 
			
		||||
 | 
			
		||||
    // ordinary references/function template arguments deduction test
 | 
			
		||||
    cxx_reference_test<int>(i);
 | 
			
		||||
    cxx_reference_test<int>(ri);
 | 
			
		||||
    cxx_reference_test<int>(ci);
 | 
			
		||||
    cxx_reference_test<int>(rci);
 | 
			
		||||
 | 
			
		||||
    cxx_reference_test<int&, int&>(i);
 | 
			
		||||
    cxx_reference_test<int&, int&>(ri);
 | 
			
		||||
    cxx_reference_test<int const&, int const&>(i);
 | 
			
		||||
    cxx_reference_test<int const&, int const&>(ri);
 | 
			
		||||
    cxx_reference_test<int const&, int const&>(ci);
 | 
			
		||||
    cxx_reference_test<int const&, int const&>(rci);
 | 
			
		||||
 | 
			
		||||
    // 'unwrap_reference' test
 | 
			
		||||
    unwrap_reference_test<int>(boost::ref(i));
 | 
			
		||||
    unwrap_reference_test<int>(boost::ref(ri));
 | 
			
		||||
    unwrap_reference_test<int const>(boost::cref(i));
 | 
			
		||||
    unwrap_reference_test<int const>(boost::cref(ci));
 | 
			
		||||
    unwrap_reference_test<int const>(boost::cref(rci));
 | 
			
		||||
 | 
			
		||||
    unwrap_reference_test<int>(i);
 | 
			
		||||
    unwrap_reference_test<int>(ri);
 | 
			
		||||
    unwrap_reference_test<int>(ci);
 | 
			
		||||
    unwrap_reference_test<int>(rci);
 | 
			
		||||
    unwrap_reference_test<int&, int&>(i);
 | 
			
		||||
    unwrap_reference_test<int&, int&>(ri);
 | 
			
		||||
    unwrap_reference_test<int const&, int const&>(i);
 | 
			
		||||
    unwrap_reference_test<int const&, int const&>(ri);
 | 
			
		||||
    unwrap_reference_test<int const&, int const&>(ci);
 | 
			
		||||
    unwrap_reference_test<int const&, int const&>(rci);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								ref_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								ref_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
// Copyright David Abrahams and Aleksey Gurtovoy
 | 
			
		||||
// 2002-2004. Distributed under the Boost Software License, Version
 | 
			
		||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
// run-time test for "boost/ref.hpp" header content
 | 
			
		||||
// see 'ref_ct_test.cpp' for compile-time part
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && !defined(__ICL)
 | 
			
		||||
# pragma warning(disable: 4786)  // identifier truncated in debug info
 | 
			
		||||
# pragma warning(disable: 4710)  // function not inlined
 | 
			
		||||
# pragma warning(disable: 4711)  // function selected for automatic inline expansion
 | 
			
		||||
# pragma warning(disable: 4514)  // unreferenced inline removed
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/ref.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
 | 
			
		||||
# pragma warning(push, 3)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BOOST_INCLUDE_MAIN
 | 
			
		||||
#include <boost/test/test_tools.hpp>
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
using namespace boost;
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
struct ref_wrapper
 | 
			
		||||
{
 | 
			
		||||
    // Used to verify implicit conversion
 | 
			
		||||
    static T* get_pointer(T& x)
 | 
			
		||||
    {
 | 
			
		||||
        return &x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static T const* get_const_pointer(T const& x)
 | 
			
		||||
    {
 | 
			
		||||
        return &x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class Arg>
 | 
			
		||||
    static T* passthru(Arg x)
 | 
			
		||||
    {
 | 
			
		||||
        return get_pointer(x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class Arg>
 | 
			
		||||
    static T const* cref_passthru(Arg x)
 | 
			
		||||
    {
 | 
			
		||||
        return get_const_pointer(x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void test(T x)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_CHECK(passthru(ref(x)) == &x);
 | 
			
		||||
        BOOST_CHECK(&ref(x).get() == &x);
 | 
			
		||||
 | 
			
		||||
        BOOST_CHECK(cref_passthru(cref(x)) == &x);
 | 
			
		||||
        BOOST_CHECK(&cref(x).get() == &x);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace unnamed
 | 
			
		||||
 | 
			
		||||
int test_main(int, char * [])
 | 
			
		||||
{
 | 
			
		||||
    ref_wrapper<int>::test(1);
 | 
			
		||||
    ref_wrapper<int const>::test(1);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,331 +0,0 @@
 | 
			
		||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
 | 
			
		||||
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <meta name="generator" content="HTML Tidy, see www.w3.org">
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 | 
			
		||||
    <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
    <meta name="ProgId" content="FrontPage.Editor.Document">
 | 
			
		||||
 | 
			
		||||
    <title>Reverse Iterator Adaptor Documentation</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
    <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
 | 
			
		||||
    "center" width="277" height="86"> 
 | 
			
		||||
 | 
			
		||||
    <h1>Reverse Iterator Adaptor</h1>
 | 
			
		||||
    Defined in header <a href=
 | 
			
		||||
    "../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a> 
 | 
			
		||||
 | 
			
		||||
    <p>The reverse iterator adaptor flips the direction of a base iterator's
 | 
			
		||||
    motion. Invoking <tt>operator++()</tt> moves the base iterator backward and
 | 
			
		||||
    invoking <tt>operator--()</tt> moves the base iterator forward. The Boost
 | 
			
		||||
    reverse iterator adaptor is better to use than the
 | 
			
		||||
    <tt>std::reverse_iterator</tt> class in situations where pairs of
 | 
			
		||||
    mutable/constant iterators are needed (e.g., in containers) because
 | 
			
		||||
    comparisons and conversions between the mutable and const versions are
 | 
			
		||||
    implemented correctly.
 | 
			
		||||
 | 
			
		||||
    <h2>Synopsis</h2>
 | 
			
		||||
<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template <class <a href=
 | 
			
		||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>,
 | 
			
		||||
            class Value, class Reference, class Pointer, class Category, class Distance>
 | 
			
		||||
  struct reverse_iterator_generator;
 | 
			
		||||
  
 | 
			
		||||
  template <class <a href=
 | 
			
		||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>>
 | 
			
		||||
  typename reverse_iterator_generator<BidirectionalIterator>::type
 | 
			
		||||
  make_reverse_iterator(BidirectionalIterator base)  
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="reverse_iterator_generator">The Reverse Iterator Type
 | 
			
		||||
    Generator</a></h2>
 | 
			
		||||
    The <tt>reverse_iterator_generator</tt> template is a <a href=
 | 
			
		||||
    "../../more/generic_programming.html#type_generator">generator</a> of
 | 
			
		||||
    reverse iterator types. The main template parameter for this class is the
 | 
			
		||||
    base <tt>BidirectionalIterator</tt> type that is being adapted. In most
 | 
			
		||||
    cases the associated types of the base iterator can be deduced using
 | 
			
		||||
    <tt>std::iterator_traits</tt>, but in some situations the user may want to
 | 
			
		||||
    override these types, so there are also template parameters for the base
 | 
			
		||||
    iterator's associated types. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class <a href=
 | 
			
		||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>,
 | 
			
		||||
          class Value, class Reference, class Pointer, class Category, class Distance>
 | 
			
		||||
class reverse_iterator_generator
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  typedef <tt><a href=
 | 
			
		||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting reverse iterator type 
 | 
			
		||||
};
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Example</h3>
 | 
			
		||||
    In this example we sort a sequence of letters and then output the sequence
 | 
			
		||||
    in descending order using reverse iterators. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  char letters[] = "hello world!";
 | 
			
		||||
  const int N = sizeof(letters)/sizeof(char) - 1;
 | 
			
		||||
  std::cout << "original sequence of letters:\t"
 | 
			
		||||
      << letters << std::endl;
 | 
			
		||||
 | 
			
		||||
  std::sort(letters, letters + N);
 | 
			
		||||
 | 
			
		||||
  // Use reverse_iterator_generator to print a sequence
 | 
			
		||||
  // of letters in reverse order.
 | 
			
		||||
  
 | 
			
		||||
  boost::reverse_iterator_generator<char*>::type
 | 
			
		||||
    reverse_letters_first(letters + N),
 | 
			
		||||
    reverse_letters_last(letters);
 | 
			
		||||
 | 
			
		||||
  std::cout << "letters in descending order:\t";
 | 
			
		||||
  std::copy(reverse_letters_first, reverse_letters_last,
 | 
			
		||||
      std::ostream_iterator<char>(std::cout));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // to be continued...
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    The output is: 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
original sequence of letters: hello world!
 | 
			
		||||
letters in descending order:  wroolllhed! 
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
    <table border>
 | 
			
		||||
      <tr>
 | 
			
		||||
        <th>Parameter
 | 
			
		||||
 | 
			
		||||
        <th>Description
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt><a href=
 | 
			
		||||
        "http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a></tt>
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        <td>The iterator type being wrapped.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Value</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The value-type of the base iterator and the resulting reverse
 | 
			
		||||
        iterator.<br>
 | 
			
		||||
         <b>Default:</b><tt>std::iterator_traits<BidirectionalIterator>::value_type</tt>
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Reference</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>reference</tt> type of the resulting iterator, and in
 | 
			
		||||
        particular, the result type of <tt>operator*()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> If <tt>Value</tt> is supplied, <tt>Value&</tt> is
 | 
			
		||||
        used. Otherwise
 | 
			
		||||
        <tt>std::iterator_traits<BidirectionalIterator>::reference</tt>
 | 
			
		||||
        is used.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Pointer</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>pointer</tt> type of the resulting iterator, and in
 | 
			
		||||
        particular, the result type of <tt>operator->()</tt>.<br>
 | 
			
		||||
         <b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
 | 
			
		||||
        otherwise
 | 
			
		||||
        <tt>std::iterator_traits<BidirectionalIterator>::pointer</tt>.
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Category</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
 | 
			
		||||
         <b>Default:</b>
 | 
			
		||||
        <tt>std::iterator_traits<BidirectionalIterator>::iterator_category</tt>
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
      <tr>
 | 
			
		||||
        <td><tt>Distance</tt> 
 | 
			
		||||
 | 
			
		||||
        <td>The <tt>difference_type</tt> for the resulting iterator.<br>
 | 
			
		||||
         <b>Default:</b>
 | 
			
		||||
        <tt>std::iterator_traits<BidirectionalIterator&gt::difference_type</tt>
 | 
			
		||||
        
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <h3>Concept Model</h3>
 | 
			
		||||
    The indirect iterator will model whichever <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/Iterators.html">standard iterator concept
 | 
			
		||||
    category</a> is modeled by the base iterator. Thus, if the base iterator is
 | 
			
		||||
    a model of <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
 | 
			
		||||
    Iterator</a> then so is the resulting indirect iterator. If the base
 | 
			
		||||
    iterator models a more restrictive concept, the resulting indirect iterator
 | 
			
		||||
    will model the same concept. The base iterator must be at least a <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional
 | 
			
		||||
    Iterator</a> 
 | 
			
		||||
 | 
			
		||||
    <h3>Members</h3>
 | 
			
		||||
    The reverse iterator type implements the member functions and operators
 | 
			
		||||
    required of the <a href=
 | 
			
		||||
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
 | 
			
		||||
    Iterator</a> concept. In addition it has the following constructor: 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
reverse_iterator_generator::type(const BidirectionalIterator& it)
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <br>
 | 
			
		||||
     <br>
 | 
			
		||||
     
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="make_reverse_iterator">The Reverse Iterator Object
 | 
			
		||||
    Generator</a></h2>
 | 
			
		||||
    The <tt>make_reverse_iterator()</tt> function provides a more convenient
 | 
			
		||||
    way to create reverse iterator objects. The function saves the user the
 | 
			
		||||
    trouble of explicitly writing out the iterator types. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
template <class BidirectionalIterator>
 | 
			
		||||
typename reverse_iterator_generator<BidirectionalIterator>::type
 | 
			
		||||
make_reverse_iterator(BidirectionalIterator base);
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
 | 
			
		||||
    <h3>Example</h3>
 | 
			
		||||
    In this part of the example we use <tt>make_reverse_iterator()</tt> to
 | 
			
		||||
    print the sequence of letters in reverse-reverse order, which is the
 | 
			
		||||
    original order. 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
  // continuing from the previous example...
 | 
			
		||||
 | 
			
		||||
  std::cout << "letters in ascending order:\t";
 | 
			
		||||
  std::copy(boost::make_reverse_iterator(reverse_letters_last),
 | 
			
		||||
      boost::make_reverse_iterator(reverse_letters_first),
 | 
			
		||||
      std::ostream_iterator<char>(std::cout));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    The output is: 
 | 
			
		||||
 | 
			
		||||
    <blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
letters in ascending order:  !dehllloorw
 | 
			
		||||
</pre>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <h2><a name="interactions">Constant/Mutable Iterator Interactions</a></h2>
 | 
			
		||||
 | 
			
		||||
    <p>One failing of the standard <tt><a
 | 
			
		||||
    href="http://www.sgi.com/tech/stl/ReverseIterator.html">reverse_iterator</a></tt>
 | 
			
		||||
    adaptor is that it doesn't properly support interactions between adapted
 | 
			
		||||
    <tt>const</tt> and non-<tt>const</tt> iterators. For example:
 | 
			
		||||
<blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
template <class T> void convert(T x) {}
 | 
			
		||||
 | 
			
		||||
// Test interactions of a matched pair of random access iterators
 | 
			
		||||
template <class Iterator, class ConstIterator>
 | 
			
		||||
void test_interactions(Iterator i, ConstIterator ci)
 | 
			
		||||
{
 | 
			
		||||
  bool eq = i == ci;               // comparisons
 | 
			
		||||
  bool ne = i != ci;            
 | 
			
		||||
  bool lt = i < ci;
 | 
			
		||||
  bool le = i <= ci;
 | 
			
		||||
  bool gt = i > ci;
 | 
			
		||||
  bool ge = i >= ci;
 | 
			
		||||
  std::size_t distance = i - ci;   // difference
 | 
			
		||||
  ci = i;                          // assignment
 | 
			
		||||
  ConstIterator ci2(i);            // construction
 | 
			
		||||
  convert<ConstIterator>(i);       // implicit conversion
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void f()
 | 
			
		||||
{
 | 
			
		||||
  typedef std::vector<int> vec;
 | 
			
		||||
  vec v;
 | 
			
		||||
  const vec& cv;
 | 
			
		||||
 | 
			
		||||
  test_interactions(v.begin(), cv.begin());   // <font color="#007F00">OK</font>
 | 
			
		||||
  test_interactions(v.rbegin(), cv.rbegin()); // <font color="#FF0000">ERRORS ON EVERY TEST!!</font>
 | 
			
		||||
</pre>
 | 
			
		||||
</blockquote>
 | 
			
		||||
Reverse iterators created with <tt>boost::reverse_iterator_generator</tt> don't have this problem, though:
 | 
			
		||||
<blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
  typedef boost::reverse_iterator_generator<vec::iterator>::type ri;
 | 
			
		||||
  typedef boost::reverse_iterator_generator<vec::const_iterator>::type cri;
 | 
			
		||||
  test_interactions(ri(v.begin()), cri(cv.begin()));   // <font color="#007F00">OK!!</font>
 | 
			
		||||
</pre>
 | 
			
		||||
</blockquote>
 | 
			
		||||
Or, more simply,
 | 
			
		||||
<blockquote>
 | 
			
		||||
<pre>
 | 
			
		||||
  test_interactions(
 | 
			
		||||
    boost::make_reverse_iterator(v.begin()), 
 | 
			
		||||
    boost::make_reverse_iterator(cv.begin()));   // <font color="#007F00">OK!!</font>
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
</blockquote>
 | 
			
		||||
 | 
			
		||||
<p>If you are wondering why there is no
 | 
			
		||||
<tt>reverse_iterator_pair_generator</tt> in the manner of <tt><a
 | 
			
		||||
href="projection_iterator.htm#projection_iterator_pair_generator">projection_iterator_pair_generator</a></tt>,
 | 
			
		||||
the answer is simple: we tried it, but found that in practice it took
 | 
			
		||||
<i>more</i> typing to use <tt>reverse_iterator_pair_generator</tt> than to
 | 
			
		||||
simply use <tt>reverse_iterator_generator</tt> twice!<br><br>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    <p>Revised 
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->08 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14892" -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <p>© Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell
 | 
			
		||||
    and distribute this document is granted provided this copyright notice
 | 
			
		||||
    appears in all copies. This document is provided "as is" without express or
 | 
			
		||||
    implied warranty, and with no claim as to its suitability for any purpose. 
 | 
			
		||||
    <!--  LocalWords:  html charset alt gif hpp BidirectionalIterator const namespace struct
 | 
			
		||||
         -->
 | 
			
		||||
     
 | 
			
		||||
    <!--  LocalWords:  ConstPointer ConstReference typename iostream int abcdefg
 | 
			
		||||
         -->
 | 
			
		||||
     <!--  LocalWords:  sizeof  PairGen pre Siek wroolllhed dehllloorw
 | 
			
		||||
         -->
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
 | 
			
		||||
// distribute this software is granted provided this copyright notice appears
 | 
			
		||||
// in all copies. This software is provided "as is" without express or implied
 | 
			
		||||
// warranty, and with no claim as to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <boost/iterator_adaptors.hpp>
 | 
			
		||||
 | 
			
		||||
int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  char letters[] = "hello world!";
 | 
			
		||||
  const int N = sizeof(letters)/sizeof(char) - 1;
 | 
			
		||||
  std::cout << "original sequence of letters:\t"
 | 
			
		||||
	    << letters << std::endl;
 | 
			
		||||
 | 
			
		||||
  std::sort(letters, letters + N);
 | 
			
		||||
 | 
			
		||||
  // Use reverse_iterator_generator to print a sequence
 | 
			
		||||
  // of letters in reverse order.
 | 
			
		||||
  
 | 
			
		||||
  boost::reverse_iterator_generator<char*>::type
 | 
			
		||||
    reverse_letters_first(letters + N),
 | 
			
		||||
    reverse_letters_last(letters);
 | 
			
		||||
 | 
			
		||||
  std::cout << "letters in descending order:\t";
 | 
			
		||||
  std::copy(reverse_letters_first, reverse_letters_last,
 | 
			
		||||
	    std::ostream_iterator<char>(std::cout));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  // Use make_reverse_iterator() to print the sequence
 | 
			
		||||
  // of letters in reverse-reverse order.
 | 
			
		||||
 | 
			
		||||
  std::cout << "letters in ascending order:\t";
 | 
			
		||||
  std::copy(boost::make_reverse_iterator(reverse_letters_last),
 | 
			
		||||
	    boost::make_reverse_iterator(reverse_letters_first),
 | 
			
		||||
	    std::ostream_iterator<char>(std::cout));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										322
									
								
								shared_container_iterator.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										322
									
								
								shared_container_iterator.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,322 @@
 | 
			
		||||
<html>
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 | 
			
		||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
<meta name="ProgId" content="FrontPage.Editor.Document">
 | 
			
		||||
<title>Shared Container Iterator Documentation</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body bgcolor="#FFFFFF" text="#000000">
 | 
			
		||||
 | 
			
		||||
<img src="../../boost.png" alt="boost.png (6897 bytes)"
 | 
			
		||||
align="center" width="277" height="86">
 | 
			
		||||
 | 
			
		||||
<h1>Shared Container Iterator</h1>
 | 
			
		||||
 | 
			
		||||
Defined in header
 | 
			
		||||
<a href="../../boost/shared_container_iterator.hpp">boost/shared_container_iterator.hpp</a>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The purpose of the shared container iterator is to attach the lifetime
 | 
			
		||||
of a container to the lifetime of its iterators. In other words, the
 | 
			
		||||
container will not be deleted until after all its iterators are
 | 
			
		||||
destroyed.  The shared container iterator is typically used to
 | 
			
		||||
implement functions that return iterators over a range of objects that
 | 
			
		||||
only need to exist for the lifetime of the iterators.  By returning a
 | 
			
		||||
pair of shared iterators from a function, the callee can return a
 | 
			
		||||
heap-allocated range of objects whose lifetime is automatically managed.
 | 
			
		||||
<p>
 | 
			
		||||
The shared container iterator augments an iterator over a shared
 | 
			
		||||
container.  It maintains a reference count on the shared 
 | 
			
		||||
container. If only shared container iterators hold references to
 | 
			
		||||
the container, the container's lifetime will end when the last shared
 | 
			
		||||
container iterator over it is destroyed.  In any case, the shared
 | 
			
		||||
container is guaranteed to persist beyond the lifetime of all
 | 
			
		||||
the iterators. In all other ways, the
 | 
			
		||||
shared container iterator behaves the same as its base iterator.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2>Synopsis</h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
namespace boost {
 | 
			
		||||
  template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>>
 | 
			
		||||
  class shared_container_iterator;
 | 
			
		||||
 | 
			
		||||
  template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>>
 | 
			
		||||
  shared_container_iterator<Container>
 | 
			
		||||
  make_shared_container_iterator(typename Container::iterator base, 
 | 
			
		||||
    boost::shared_ptr<Container> const& container);
 | 
			
		||||
 | 
			
		||||
  std::pair<
 | 
			
		||||
    typename shared_container_iterator<Container>,
 | 
			
		||||
    typename shared_container_iterator<Container>
 | 
			
		||||
  >
 | 
			
		||||
  make_shared_container_range(boost::shared_ptr<Container> const& container);
 | 
			
		||||
}
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<h2><a name="generator">The Shared Container Iterator Type</a></h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <typename Container> class shared_container_iterator;
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
The class template <tt>shared_container_iterator</tt> 
 | 
			
		||||
is the shared container iterator type.  The <tt>Container</tt> template
 | 
			
		||||
type argument must model the
 | 
			
		||||
<a href="http://www.sgi.com/tech/stl/Container.html">Container</a>
 | 
			
		||||
concept.
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The following example illustrates how to create an iterator that 
 | 
			
		||||
regulates the lifetime of a reference counted <tt>std::vector</tt>.
 | 
			
		||||
Though the original shared pointer <tt>ints</tt> ceases to exist
 | 
			
		||||
after <tt>set_range()</tt> returns, the
 | 
			
		||||
<tt>shared_counter_iterator</tt> objects maintain references to the
 | 
			
		||||
      underlying vector and thereby extend the container's lifetime.
 | 
			
		||||
<p>
 | 
			
		||||
<a href="./shared_iterator_example1.cpp">shared_iterator_example1.cpp</a>:
 | 
			
		||||
<PRE>
 | 
			
		||||
<font color="#008040">#include "shared_container_iterator.hpp"</font>
 | 
			
		||||
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
 | 
			
		||||
<font color="#008040">#include <algorithm></font>
 | 
			
		||||
<font color="#008040">#include <iostream></font>
 | 
			
		||||
<font color="#008040">#include <vector></font>
 | 
			
		||||
 | 
			
		||||
<B>typedef</B> boost::shared_container_iterator< std::vector<<B>int</B>> > iterator;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<B>void</B> set_range(iterator& i, iterator& end)  {
 | 
			
		||||
 | 
			
		||||
  boost::shared_ptr< std::vector<<B>int</B>> > ints(<B>new</B> std::vector<<B>int</B>>());
 | 
			
		||||
  
 | 
			
		||||
  ints->push_back(<font color="#0000A0">0</font>);
 | 
			
		||||
  ints->push_back(<font color="#0000A0">1</font>);
 | 
			
		||||
  ints->push_back(<font color="#0000A0">2</font>);
 | 
			
		||||
  ints->push_back(<font color="#0000A0">3</font>);
 | 
			
		||||
  ints->push_back(<font color="#0000A0">4</font>);
 | 
			
		||||
  ints->push_back(<font color="#0000A0">5</font>);
 | 
			
		||||
  
 | 
			
		||||
  i = iterator(ints->begin(),ints);
 | 
			
		||||
  end = iterator(ints->end(),ints);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<B>int</B> main() {
 | 
			
		||||
 | 
			
		||||
  iterator i,end;
 | 
			
		||||
 | 
			
		||||
  set_range(i,end);
 | 
			
		||||
 | 
			
		||||
  std::copy(i,end,std::ostream_iterator<<B>int</B>>(std::cout,<font color="#0000FF">","</font>));
 | 
			
		||||
  std::cout.put(<font color="#0000FF">'\n'</font>);
 | 
			
		||||
 | 
			
		||||
  <B>return</B> <font color="#0000A0">0</font>;
 | 
			
		||||
}
 | 
			
		||||
</PRE>
 | 
			
		||||
 | 
			
		||||
The output from this part is:
 | 
			
		||||
<pre>
 | 
			
		||||
0,1,2,3,4,5,
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Template Parameters</h3>
 | 
			
		||||
 | 
			
		||||
<Table border>
 | 
			
		||||
<TR>
 | 
			
		||||
<TH>Parameter</TH><TH>Description</TH>
 | 
			
		||||
</TR>
 | 
			
		||||
 | 
			
		||||
<TR>
 | 
			
		||||
<TD><a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a></TD>
 | 
			
		||||
<TD>The type of the container that we wish to iterate over. It must be 
 | 
			
		||||
a model of the 
 | 
			
		||||
<a href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a>
 | 
			
		||||
concept.
 | 
			
		||||
</TD>
 | 
			
		||||
</TR>
 | 
			
		||||
</Table>
 | 
			
		||||
 | 
			
		||||
<h3>Model of</h3>
 | 
			
		||||
 | 
			
		||||
The <tt>shared_container_iterator<Container></tt> type models the
 | 
			
		||||
same iterator concept as the base iterator
 | 
			
		||||
    (<tt>Container::iterator</tt>).
 | 
			
		||||
 | 
			
		||||
<h3>Members</h3>
 | 
			
		||||
 | 
			
		||||
The shared container iterator type implements the member functions and
 | 
			
		||||
operators required of the <a
 | 
			
		||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
 | 
			
		||||
concept, though only operations defined for the base iterator will be valid.
 | 
			
		||||
In addition it has the following constructor:
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
shared_container_iterator(Container::iterator const& it,
 | 
			
		||||
                          boost::shared_ptr<Container> const& container)
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<h2><a name="make_iterator">The Shared Container Iterator Object Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <typename Container>
 | 
			
		||||
shared_container_iterator<Container>
 | 
			
		||||
make_shared_container_iterator(Container::iterator base,
 | 
			
		||||
                               boost::shared_ptr<Container> const& container)
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
This function provides an alternative to directly constructing a
 | 
			
		||||
shared container iterator.  Using the object generator, a shared
 | 
			
		||||
container iterator can be created and passed to a function without
 | 
			
		||||
explicitly specifying its type.
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
This example, similar to the previous, uses 
 | 
			
		||||
<tt>make_shared_container_iterator()</tt> to create the iterators.
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
<a href="./shared_iterator_example2.cpp">shared_iterator_example2.cpp</a>:
 | 
			
		||||
 | 
			
		||||
<PRE>
 | 
			
		||||
<font color="#008040">#include "shared_container_iterator.hpp"</font>
 | 
			
		||||
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
 | 
			
		||||
<font color="#008040">#include <algorithm></font>
 | 
			
		||||
<font color="#008040">#include <iterator></font>
 | 
			
		||||
<font color="#008040">#include <iostream></font>
 | 
			
		||||
<font color="#008040">#include <vector></font>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<B>template</B> <<B>typename</B> Iterator>
 | 
			
		||||
<B>void</B> print_range_nl (Iterator begin, Iterator end) {
 | 
			
		||||
  <B>typedef</B> <B>typename</B> std::iterator_traits<Iterator>::value_type val;
 | 
			
		||||
  std::copy(begin,end,std::ostream_iterator<val>(std::cout,<font color="#0000FF">","</font>));
 | 
			
		||||
  std::cout.put(<font color="#0000FF">'\n'</font>);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<B>int</B> main() {
 | 
			
		||||
 | 
			
		||||
  <B>typedef</B> boost::shared_ptr< std::vector<<B>int</B>> > ints_t;
 | 
			
		||||
  {
 | 
			
		||||
    ints_t ints(<B>new</B> std::vector<<B>int</B>>());
 | 
			
		||||
 | 
			
		||||
    ints->push_back(<font color="#0000A0">0</font>);
 | 
			
		||||
    ints->push_back(<font color="#0000A0">1</font>);
 | 
			
		||||
    ints->push_back(<font color="#0000A0">2</font>);
 | 
			
		||||
    ints->push_back(<font color="#0000A0">3</font>);
 | 
			
		||||
    ints->push_back(<font color="#0000A0">4</font>);
 | 
			
		||||
    ints->push_back(<font color="#0000A0">5</font>);
 | 
			
		||||
 | 
			
		||||
    print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
 | 
			
		||||
		   boost::make_shared_container_iterator(ints->end(),ints));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  <B>return</B> <font color="#0000A0">0</font>;
 | 
			
		||||
}
 | 
			
		||||
</PRE>
 | 
			
		||||
 | 
			
		||||
Observe that the <tt>shared_container_iterator</tt> type is never
 | 
			
		||||
explicitly named. The output from this example is the same as the previous.
 | 
			
		||||
 | 
			
		||||
<h2><a name="make_range">The Shared Container Iterator Range Generator</a></h2>
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
template <typename Container>
 | 
			
		||||
std::pair<
 | 
			
		||||
  shared_container_iterator<Container>,
 | 
			
		||||
  shared_container_iterator<Container>
 | 
			
		||||
>
 | 
			
		||||
make_shared_container_range(boost::shared_ptr<Container> const& container);
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
Class <tt>shared_container_iterator</tt> is meant primarily to return,
 | 
			
		||||
using iterators, a range of values that we can guarantee will be alive as 
 | 
			
		||||
long as the iterators are. This is a convenience
 | 
			
		||||
function to do just that. It is equivalent to
 | 
			
		||||
 | 
			
		||||
<pre>
 | 
			
		||||
std::make_pair(make_shared_container_iterator(container->begin(),container),
 | 
			
		||||
               make_shared_container_iterator(container->end(),container));
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<h3>Example</h3>
 | 
			
		||||
 | 
			
		||||
In the following example, a range of values is returned as a pair of
 | 
			
		||||
<tt>shared_container_iterator</tt> objects.  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
<a href="./shared_iterator_example3.cpp">shared_iterator_example3.cpp</a>:
 | 
			
		||||
 | 
			
		||||
<PRE>
 | 
			
		||||
<font color="#008040">#include "shared_container_iterator.hpp"</font>
 | 
			
		||||
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
 | 
			
		||||
<font color="#008040">#include "boost/tuple/tuple.hpp" // for boost::tie</font>
 | 
			
		||||
<font color="#008040">#include <algorithm>              // for std::copy</font>
 | 
			
		||||
<font color="#008040">#include <iostream>              </font>
 | 
			
		||||
<font color="#008040">#include <vector></font>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<B>typedef</B> boost::shared_container_iterator< std::vector<<B>int</B>> > iterator; 
 | 
			
		||||
 | 
			
		||||
std::pair<iterator,iterator>
 | 
			
		||||
return_range() {
 | 
			
		||||
  boost::shared_ptr< std::vector<<B>int</B>> > range(<B>new</B> std::vector<<B>int</B>>());
 | 
			
		||||
  range->push_back(<font color="#0000A0">0</font>);
 | 
			
		||||
  range->push_back(<font color="#0000A0">1</font>);
 | 
			
		||||
  range->push_back(<font color="#0000A0">2</font>);
 | 
			
		||||
  range->push_back(<font color="#0000A0">3</font>);
 | 
			
		||||
  range->push_back(<font color="#0000A0">4</font>);
 | 
			
		||||
  range->push_back(<font color="#0000A0">5</font>);
 | 
			
		||||
  <B>return</B> boost::make_shared_container_range(range);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<B>int</B> main() {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  iterator i,end;
 | 
			
		||||
  
 | 
			
		||||
  boost::tie(i,end) = return_range();
 | 
			
		||||
 | 
			
		||||
  std::copy(i,end,std::ostream_iterator<<B>int</B>>(std::cout,<font color="#0000FF">","</font>));
 | 
			
		||||
  std::cout.put(<font color="#0000FF">'\n'</font>);
 | 
			
		||||
 | 
			
		||||
  <B>return</B> <font color="#0000A0">0</font>;
 | 
			
		||||
}
 | 
			
		||||
</PRE>
 | 
			
		||||
 | 
			
		||||
Though the <tt>range</tt> object only lives for the duration of the
 | 
			
		||||
<tt>return_range</tt> call, the reference counted
 | 
			
		||||
<tt>std::vector</tt> will live until <tt>i</tt> and <tt>end</tt>
 | 
			
		||||
are both destroyed.  The output from this example is the same as
 | 
			
		||||
the previous two.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<!-- hhmts start -->
 | 
			
		||||
Last modified: Mon Aug 11 11:27:03 EST 2003
 | 
			
		||||
<!-- hhmts end -->
 | 
			
		||||
<p><EFBFBD> Copyright 2003 The Trustees of Indiana University.
 | 
			
		||||
 Use, modification and distribution is subject to the Boost Software 
 | 
			
		||||
 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
 http:www.boost.org/LICENSE_1_0.txt)</p>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										42
									
								
								shared_iterator_example1.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								shared_iterator_example1.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// Copyright 2003 The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification and distribution is subject to the Boost Software 
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
#include "boost/shared_container_iterator.hpp"
 | 
			
		||||
#include "boost/shared_ptr.hpp"
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
typedef boost::shared_container_iterator< std::vector<int> > iterator;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void set_range(iterator& i, iterator& end)  {
 | 
			
		||||
 | 
			
		||||
  boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
 | 
			
		||||
  
 | 
			
		||||
  ints->push_back(0);
 | 
			
		||||
  ints->push_back(1);
 | 
			
		||||
  ints->push_back(2);
 | 
			
		||||
  ints->push_back(3);
 | 
			
		||||
  ints->push_back(4);
 | 
			
		||||
  ints->push_back(5);
 | 
			
		||||
  
 | 
			
		||||
  i = iterator(ints->begin(),ints);
 | 
			
		||||
  end = iterator(ints->end(),ints);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
 | 
			
		||||
  iterator i,end;
 | 
			
		||||
 | 
			
		||||
  set_range(i,end);
 | 
			
		||||
 | 
			
		||||
  std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
 | 
			
		||||
  std::cout.put('\n');
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								shared_iterator_example2.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								shared_iterator_example2.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
// Copyright 2003 The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification and distribution is subject to the Boost Software 
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
#include "boost/shared_container_iterator.hpp"
 | 
			
		||||
#include "boost/shared_ptr.hpp"
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template <typename Iterator>
 | 
			
		||||
void print_range_nl (Iterator begin, Iterator end) {
 | 
			
		||||
  typedef typename std::iterator_traits<Iterator>::value_type val;
 | 
			
		||||
  std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
 | 
			
		||||
  std::cout.put('\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
 | 
			
		||||
  typedef boost::shared_ptr< std::vector<int> > ints_t;
 | 
			
		||||
  {
 | 
			
		||||
    ints_t ints(new std::vector<int>());
 | 
			
		||||
 | 
			
		||||
    ints->push_back(0);
 | 
			
		||||
    ints->push_back(1);
 | 
			
		||||
    ints->push_back(2);
 | 
			
		||||
    ints->push_back(3);
 | 
			
		||||
    ints->push_back(4);
 | 
			
		||||
    ints->push_back(5);
 | 
			
		||||
 | 
			
		||||
    print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
 | 
			
		||||
                   boost::make_shared_container_iterator(ints->end(),ints));
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								shared_iterator_example3.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								shared_iterator_example3.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
// Copyright 2003 The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification and distribution is subject to the Boost Software 
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
#include "boost/shared_container_iterator.hpp"
 | 
			
		||||
#include "boost/shared_ptr.hpp"
 | 
			
		||||
#include "boost/tuple/tuple.hpp" // for boost::tie
 | 
			
		||||
#include <algorithm>              // for std::copy
 | 
			
		||||
#include <iostream>              
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef boost::shared_container_iterator< std::vector<int> > iterator;
 | 
			
		||||
 | 
			
		||||
std::pair<iterator,iterator>
 | 
			
		||||
return_range() {
 | 
			
		||||
  boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
 | 
			
		||||
  range->push_back(0);
 | 
			
		||||
  range->push_back(1);
 | 
			
		||||
  range->push_back(2);
 | 
			
		||||
  range->push_back(3);
 | 
			
		||||
  range->push_back(4);
 | 
			
		||||
  range->push_back(5);
 | 
			
		||||
  return boost::make_shared_container_range(range);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  iterator i,end;
 | 
			
		||||
  
 | 
			
		||||
  boost::tie(i,end) = return_range();
 | 
			
		||||
 | 
			
		||||
  std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
 | 
			
		||||
  std::cout.put('\n');
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								shared_iterator_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								shared_iterator_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
// Copyright 2003 The Trustees of Indiana University.
 | 
			
		||||
 | 
			
		||||
// Use, modification and distribution is subject to the Boost Software 
 | 
			
		||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 | 
			
		||||
//  Shared container iterator adaptor 
 | 
			
		||||
//  Author: Ronald Garcia
 | 
			
		||||
//  See http://boost.org/libs/utility/shared_container_iterator.html 
 | 
			
		||||
//  for documentation. 
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// shared_iterator_test.cpp - Regression tests for shared_container_iterator.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "boost/shared_container_iterator.hpp"
 | 
			
		||||
#include "boost/shared_ptr.hpp"
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
struct resource {
 | 
			
		||||
  static int count;
 | 
			
		||||
  resource() { ++count; }
 | 
			
		||||
  resource(resource const&) { ++count; }
 | 
			
		||||
  ~resource() { --count; }
 | 
			
		||||
};
 | 
			
		||||
int resource::count = 0;
 | 
			
		||||
 | 
			
		||||
typedef std::vector<resource> resources_t;
 | 
			
		||||
 | 
			
		||||
typedef boost::shared_container_iterator< resources_t > iterator;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void set_range(iterator& i, iterator& end)  {
 | 
			
		||||
 | 
			
		||||
  boost::shared_ptr< resources_t > objs(new resources_t());
 | 
			
		||||
 | 
			
		||||
  for (int j = 0; j != 6; ++j)
 | 
			
		||||
    objs->push_back(resource());
 | 
			
		||||
  
 | 
			
		||||
  i = iterator(objs->begin(),objs);
 | 
			
		||||
  end = iterator(objs->end(),objs);
 | 
			
		||||
  assert(resource::count == 6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
 | 
			
		||||
  assert(resource::count == 0);
 | 
			
		||||
  
 | 
			
		||||
  {
 | 
			
		||||
    iterator i;
 | 
			
		||||
    {
 | 
			
		||||
      iterator end;
 | 
			
		||||
      set_range(i,end);
 | 
			
		||||
      assert(resource::count == 6);
 | 
			
		||||
    }
 | 
			
		||||
    assert(resource::count == 6);
 | 
			
		||||
  }
 | 
			
		||||
  assert(resource::count == 0);
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								sublibs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								sublibs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
The existance of this file tells the regression reporting programs that the directory contains sub-directories which are libraries.
 | 
			
		||||
							
								
								
									
										43
									
								
								test/Jamfile
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										43
									
								
								test/Jamfile
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
# Copyright David Abrahams 2003. Permission to copy, use,
 | 
			
		||||
# modify, sell and distribute this software is granted provided this
 | 
			
		||||
# copyright notice appears in all copies. This software is provided
 | 
			
		||||
# "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
# to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
# For more information, see http://www.boost.org/
 | 
			
		||||
 | 
			
		||||
subproject libs/utility/test ;
 | 
			
		||||
 | 
			
		||||
# bring in rules for testing
 | 
			
		||||
import testing ;
 | 
			
		||||
 | 
			
		||||
# Make tests run by default.
 | 
			
		||||
DEPENDS all : test ;
 | 
			
		||||
 | 
			
		||||
local test_monitor = <lib>@boost/libs/test/build/boost_test_exec_monitor ;
 | 
			
		||||
 | 
			
		||||
# 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_monitor) : -u ]
 | 
			
		||||
        [ run ../current_function_test.cpp : : : <test-info>always_show_run_output ]
 | 
			
		||||
        [ run ../iterators_test.cpp $(test_monitor) ]
 | 
			
		||||
        [ run next_prior_test.cpp $(test_monitor) ]
 | 
			
		||||
        [ compile-fail ../noncopyable_test.cpp ]
 | 
			
		||||
        [ run ../numeric_traits_test.cpp ]
 | 
			
		||||
        [ run ../operators_test.cpp $(test_monitor) ]
 | 
			
		||||
        [ compile ../ref_ct_test.cpp  ]
 | 
			
		||||
        [ run ../ref_test.cpp $(test_monitor) ]
 | 
			
		||||
        [ 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 ]
 | 
			
		||||
    ;
 | 
			
		||||
							
								
								
									
										36
									
								
								test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
# Copyright David Abrahams 2003. Permission to copy, use,
 | 
			
		||||
# modify, sell and distribute this software is granted provided this
 | 
			
		||||
# copyright notice appears in all copies. This software is provided
 | 
			
		||||
# "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
# to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
# 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 : -u ]
 | 
			
		||||
        [ run ../current_function_test.cpp : : : <test-info>always_show_run_output ]
 | 
			
		||||
        [ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor ]
 | 
			
		||||
        [ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor ]
 | 
			
		||||
        [ compile-fail ../noncopyable_test.cpp ]
 | 
			
		||||
        [ run ../numeric_traits_test.cpp ]
 | 
			
		||||
        [ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor ]
 | 
			
		||||
        [ compile ../ref_ct_test.cpp  ]
 | 
			
		||||
        [ run ../ref_test.cpp ../../test/build//boost_test_exec_monitor ]
 | 
			
		||||
        [ 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 ]
 | 
			
		||||
    ;
 | 
			
		||||
							
								
								
									
										79
									
								
								test/next_prior_test.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										79
									
								
								test/next_prior_test.cpp
									
									
									
									
									
										Executable 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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								test/result_of_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								test/result_of_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
// 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; };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct X {};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  using namespace boost;
 | 
			
		||||
 | 
			
		||||
  typedef int (*func_ptr)(float, double);
 | 
			
		||||
  typedef int (&func_ref)(float, double);
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
  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<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<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));
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								throw_exception.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								throw_exception.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
<!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">
 | 
			
		||||
					<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
 | 
			
		||||
				</td>
 | 
			
		||||
				<td align="middle">
 | 
			
		||||
					<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. Permission to copy, use, modify, sell and 
 | 
			
		||||
				distribute this document is granted provided this copyright notice appears in 
 | 
			
		||||
				all copies. This document is provided "as is" without express or implied 
 | 
			
		||||
				warranty, and with no claim as to its suitability for any purpose.</small></p>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user