Compare commits

...

36 Commits

Author SHA1 Message Date
199e0c00be This commit was manufactured by cvs2svn to create tag
'Version_1_29_0'.

[SVN r15904]
2002-10-11 15:17:55 +00:00
7c9c9c9a1c Updated documentation
[SVN r15570]
2002-09-30 16:49:30 +00:00
b0b821c0d1 This commit was manufactured by cvs2svn to create branch 'RC_1_29_0'.
[SVN r15460]
2002-09-19 20:49:39 +00:00
aff985a563 explicit "private" inheritance to avoid compiler warnings (MIPSpro)
[SVN r15422]
2002-09-17 21:06:32 +00:00
db425222d5 mpl_v2 branch checkin
[SVN r15258]
2002-09-11 05:35:41 +00:00
e20af510f7 Initial Revision
[SVN r15254]
2002-09-10 16:13:08 +00:00
d8230c6a73 Added Shared Container Iterator adaptor to iterator adaptor library.
[SVN r15169]
2002-09-05 14:05:29 +00:00
f5690787bf Distinguish between VC++ versions
[SVN r15127]
2002-09-01 14:57:40 +00:00
a4fd7b32dd Misc Kylix fixes
[SVN r15086]
2002-08-25 11:57:37 +00:00
f4336ec693 fixed typo.
[SVN r14798]
2002-08-12 20:47:54 +00:00
03d906976b Reduced probes from 10,000 to 1,000 to speed regression tests
[SVN r14789]
2002-08-12 15:05:23 +00:00
4ba6a96822 fix test_main signature
[SVN r14783]
2002-08-12 13:22:40 +00:00
1ea4140d56 Added tests for BOOST_NO_STD_ITERATOR_TRAITS
[SVN r14654]
2002-07-31 11:25:25 +00:00
351d4ecb15 Document policies() member of iterator_adaptor
[SVN r14613]
2002-07-26 00:03:24 +00:00
7fbf84dcc6 BaseType -> Base in one more place
[SVN r14605]
2002-07-25 19:10:05 +00:00
3ff49b272d fixup
[SVN r14598]
2002-07-25 14:16:54 +00:00
5b52e3d418 Fix doc based on Beman's feedback
[SVN r14596]
2002-07-25 13:52:48 +00:00
8c0eb498d3 Fix unversioned VC++ checks
[SVN r14436]
2002-07-13 12:26:19 +00:00
48a81ef7ea VC++ fixes
[SVN r14435]
2002-07-13 12:22:51 +00:00
f7610c9b26 fix link
[SVN r14318]
2002-07-05 23:51:20 +00:00
1755eaf019 Merged from RC_1_28_0
[SVN r13944]
2002-05-16 00:56:42 +00:00
6b8b218efb Removed tabs, fixed end of files.
[SVN r13803]
2002-05-10 11:35:38 +00:00
333d79b345 Add index.html so automatic tools work correctly
[SVN r13725]
2002-05-07 19:23:05 +00:00
f0fa436fe4 Added new config macro BOOST_HAS_MS_INT64 to detect presence of __int64 data type.
Modified boost source to use BOOST_HAS_LONG_LONG and BOOST_HAS_MS_INT64
   where appropriate to do so.


[SVN r13714]
2002-05-07 11:24:29 +00:00
13e6d78fa8 Fixes for Borland C++ Builder 6
[SVN r13662]
2002-05-04 11:03:42 +00:00
7126ea2685 Borland C++ Builder 6 fixes
[SVN r13659]
2002-05-04 10:55:15 +00:00
a37518cb4a Fixed broken links.
[SVN r13574]
2002-04-27 11:05:49 +00:00
64b3e8c3bd add missing #include <iterator>
[SVN r13554]
2002-04-23 19:52:11 +00:00
339937380e MSVC fixes.
[SVN r13476]
2002-04-13 13:19:57 +00:00
6156f0d302 Roll addressof() patch back in!
[SVN r13433]
2002-04-10 17:01:35 +00:00
00560e8e17 addressof.hpp:
- Peter Dimov suggested a fix to deal with those evil cv-qualifiers


[SVN r13431]
2002-04-10 14:47:32 +00:00
029ff9828f Roll back addressof() patch temporarily
[SVN r13428]
2002-04-10 09:48:30 +00:00
ec188c7c3e Make local classes nonlocal to silence annoying warnings from Borland C++
[SVN r13418]
2002-04-10 04:00:22 +00:00
0a0296a5d0 ref.hpp:
- Use addressof() instead of & operator


[SVN r13416]
2002-04-10 03:36:17 +00:00
6e26a5bbe7 boost/utility.hpp:
- Include boost/utility/addressof.hpp

boost/utility/addressof.hpp:
  - addressof() implementation

libs/utility/utility.htm:
  - Document addressof

libs/utility/addressof_test.cpp:
  - Test addressof()


[SVN r13414]
2002-04-10 03:31:18 +00:00
dc1b6246a0 boost/ref.hpp:
- Added get_pointer method to return a pointer (instead of a reference)

libs/bind/ref.html:
  - Document get_pointer


[SVN r13322]
2002-03-31 00:24:00 +00:00
35 changed files with 1827 additions and 80 deletions

648
Collection.html Normal file
View 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="../../c++boost.gif" 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 &quot;own&quot; 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() &gt;= 0
</TD>
</TR>
<!--
<TR>
<TD VAlign=top>
Maximum size
</TD>
<TD VAlign=top>
<tt>a.max_size()</tt>
</TD>
<TD VAlign=top>
&nbsp;
</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() &gt;= 0 &amp;&amp; a.max_size() &gt;= 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>
&nbsp;
</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>
&nbsp;
</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&lt;bool&gt;</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>
Font
</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.first())</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 &lt;= n &lt; 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 &copy 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>

46
addressof_test.cpp Normal file
View File

@ -0,0 +1,46 @@
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
// Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// For more information, see http://www.boost.org
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <boost/utility.hpp>
struct useless_type {};
class nonaddressable {
public:
void dummy(); // Silence GCC warning: all member of class are private
private:
useless_type operator&() const;
};
int test_main(int, char*[])
{
nonaddressable* px = new nonaddressable();
nonaddressable& x = *px;
BOOST_TEST(boost::addressof(x) == px);
const nonaddressable& cx = *px;
BOOST_TEST(boost::addressof(cx) == static_cast<const nonaddressable*>(px));
volatile nonaddressable& vx = *px;
BOOST_TEST(boost::addressof(vx) == static_cast<volatile nonaddressable*>(px));
const volatile nonaddressable& cvx = *px;
BOOST_TEST(boost::addressof(cvx) == static_cast<const volatile nonaddressable*>(px));
return 0;
}

View File

@ -103,7 +103,7 @@ void random_sorted_sequence(T& seq)
sort_by_value(seq);
}
# if defined(BOOST_MSVC) && !defined(__SGI_STL_PORT)
# if defined(BOOST_MSVC) && BOOST_MSVC < 1300 && !defined(__SGI_STL_PORT)
// VC6's standard lib doesn't have a template member function for list::sort()
template <>
void random_sorted_sequence(std::list<std::string>& result)

View File

@ -5,7 +5,7 @@
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>
@ -592,7 +592,8 @@ would prevent template argument deduction from functioning.</p>
<p>The call_traits template will &quot;optimize&quot; 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
@ -751,7 +752,8 @@ 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>
discussion list at <a
href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
<p>.</p>

View File

@ -408,7 +408,7 @@ template struct call_traits_test<int[2], true>;
#endif
#endif
#ifdef BOOST_MSVC
#if defined(BOOST_MSVC) && _MSC_VER <= 1300
unsigned int expected_failures = 14;
#elif defined(__SUNPRO_CC)
#if(__SUNPRO_CC <= 0x520)

View File

@ -329,7 +329,7 @@ void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_para
BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
}
int test_main(int, char **)
int test_main(int, char *[])
{
// declare some variables to pass to the tester:
non_empty1 ne1(2);

View File

@ -35,13 +35,15 @@ int main(int, char*[])
std::vector<std::vector<int>::iterator> pointers;
// VC6 gets an internal compiler error on this
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
// Use counting iterator to fill in the array of pointers.
// causes an ICE with MSVC6
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
std::copy(boost::make_counting_iterator(numbers.begin()),
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
#endif
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1300)
// 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 "

View File

@ -240,14 +240,14 @@ int main()
test_integer<unsigned int>();
test_integer<long>();
test_integer<unsigned long>();
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
#if defined(BOOST_HAS_LONG_LONG)
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)
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || defined(__SGI_STL_PORT)
// Test user-defined type.
test_integer<my_int1>();
test_integer<my_int2>();

View File

@ -22,7 +22,7 @@ int main()
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
const int N = sizeof(numbers_)/sizeof(int);
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
// Assume there won't be proper iterator traits for pointers. This
// is just a wrapper for int* which has the right traits.
typedef boost::iterator_adaptor<int*, boost::default_iterator_policies, int> base_iterator;

View File

@ -346,7 +346,7 @@ int main()
test_integer<unsigned int>();
test_integer<long>();
test_integer<unsigned long>();
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
#if defined(BOOST_HAS_LONG_LONG)
test_integer<long long>();
test_integer<unsigned long long>();
#endif

View File

@ -95,7 +95,7 @@ struct call_traits<T&>
typedef T& param_type; // hh removed const
};
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
// these are illegal specialisations; cv-qualifies applied to
// references have no effect according to [8.3.2p1],
// C++ Builder requires them though as it treats cv-qualified

View File

@ -98,21 +98,21 @@ struct call_traits_chooser<false, false, true>
template <bool size_is_small>
struct call_traits_sizeof_chooser2
{
template <class T>
struct small_rebind
{
typedef simple_call_traits<T> small_type;
};
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 <class T>
struct small_rebind
{
typedef standard_call_traits<T> small_type;
};
};
template <>
@ -121,10 +121,10 @@ 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;
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;
};
};
@ -138,8 +138,8 @@ private:
::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;
typedef typename chooser::template rebind<T> bound_type;
typedef typename bound_type::type call_traits_type;
public:
typedef typename call_traits_type::value_type value_type;
typedef typename call_traits_type::reference reference;

View File

@ -168,7 +168,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.

View File

@ -6,12 +6,13 @@
# endif
# include <boost/config.hpp>
# include <boost/utility/addressof.hpp>
//
// ref.hpp - ref/cref, useful helper functions
//
// Copyright (C) 1999, 2000 Jaakko J<>rvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2001 Peter Dimov
// Copyright (C) 2001, 2002 Peter Dimov
// Copyright (C) 2002 David Abrahams
//
// Permission to copy, use, modify, sell and distribute this software
@ -30,18 +31,28 @@ 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_(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__ <= 0x551)
# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)
# define BOOST_REF_CONST
# else
# define BOOST_REF_CONST const

View File

@ -17,6 +17,7 @@
#include <boost/checked_delete.hpp>
#include <boost/utility/base_from_member.hpp>
#include <boost/utility/addressof.hpp>
namespace boost
{

View File

@ -0,0 +1,31 @@
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
// Doug Gregor (gregod@cs.rpi.edu)
// Peter Dimov
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// For more information, see http://www.boost.org
#ifndef BOOST_UTILITY_ADDRESSOF_HPP
#define BOOST_UTILITY_ADDRESSOF_HPP
namespace boost {
// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov)
template <typename T> T* addressof(T& v)
{
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}
}
#endif // BOOST_UTILITY_ADDRESSOF_HPP

View File

@ -0,0 +1,82 @@
// (C) 2002, Fernando Luis Cacciola Carballal.
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// 21 Ago 2002 (Created) Fernando Cacciola
//
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
#include "boost/detail/select_type.hpp"
#include "boost/type_traits/cv_traits.hpp"
namespace boost {
namespace vinit_detail {
template<class T>
class const_T_base
{
protected :
const_T_base() : x() {}
T x ;
} ;
template<class T>
struct non_const_T_base
{
protected :
non_const_T_base() : x() {}
mutable T x ;
} ;
template<class T>
struct select_base
{
typedef typename
detail::if_true< ::boost::is_const<T>::value >
::template then< const_T_base<T>, non_const_T_base<T> >::type type ;
} ;
} // namespace vinit_detail
template<class T>
class value_initialized : private vinit_detail::select_base<T>::type
{
public :
value_initialized() {}
operator T&() const { return this->x ; }
T& data() const { return this->x ; }
} ;
template<class T>
T const& get ( value_initialized<T> const& x )
{
return x.data() ;
}
template<class T>
T& get ( value_initialized<T>& x )
{
return x.data() ;
}
} // namespace boost
#endif

34
index.html Normal file
View 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="../../c++boost.gif" WIDTH="276" HEIGHT="86" align="center">Boost
Utility Library</h1>
<p>The Boost Utility Library isn't really a single library at all.&nbsp; 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.&nbsp; Take a look:</p>
<blockquote>
<p><a href="base_from_member.html">base_from_member</a><br>
<a href="call_traits.htm">call_traits.htm</a><br>
<a href="compressed_pair.htm">compressed_pair.htm</a><br>
<a href="operators.htm">operators.htm</a><br>
<a href="tie.html">tie</a><br>
<a href="utility.htm">utility.htm</a></p>
</blockquote>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 May, 2002<!--webbot bot="Timestamp" endspan i-checksum="13976" --></p>
<p>&nbsp;</p>
</body>
</html>

View File

@ -51,7 +51,7 @@ int main(int, char*[])
// Example of using make_indirect_iterator()
#ifndef BOOST_MSVC
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));

View File

@ -31,7 +31,7 @@ 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)
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || !defined(__STL_DEBUG)
storage store(1000);
std::generate(store.begin(), store.end(), rand);
@ -46,7 +46,7 @@ void more_indirect_iterator_tests()
typedef boost::indirect_iterator_pair_generator<
pointer_deque::iterator
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, int
#endif
> IndirectDeque;
@ -75,7 +75,7 @@ void more_indirect_iterator_tests()
typedef boost::indirect_iterator_generator<
iterator_set::iterator
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, int
#endif
>::type indirect_set_iterator;
@ -117,7 +117,7 @@ main()
ptr[k] = array + k;
typedef boost::indirect_iterator_generator<dummyT**
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, dummyT
#endif
>::type indirect_iterator;
@ -127,7 +127,7 @@ main()
indirect_iterator i(ptr);
boost::random_access_iterator_test(i, N, array);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
#endif
@ -139,7 +139,7 @@ main()
dummyT*const* const_ptr = ptr;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
#endif
boost::const_nonconst_iterator_test(i, ++j);

View File

@ -133,7 +133,7 @@ main()
boost::function_requires<
boost::RandomAccessIteratorPoliciesConcept<
boost::default_iterator_policies,
boost::iterator_adaptor<int*, boost::default_iterator_policies>,
boost::iterator_adaptor<storage::iterator, boost::default_iterator_policies>,
boost::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t,
int*, int&>
> >();
@ -156,7 +156,7 @@ main()
boost::default_iterator_policies,
boost::value_type_is<const int> > Iter1;
BOOST_STATIC_ASSERT((boost::is_same<Iter1::value_type, int>::value));
#if defined(__BORLANDC__) || defined(BOOST_MSVC)
#if defined(__BORLANDC__) || defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// We currently don't know how to workaround this bug.
BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, int&>::value));
BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, int*>::value));
@ -224,7 +224,7 @@ main()
std::reverse(reversed, reversed + N);
typedef boost::reverse_iterator_generator<dummyT*
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT
#endif
>::type reverse_iterator;
@ -232,12 +232,12 @@ main()
reverse_iterator i(reversed + N);
boost::random_access_iterator_test(i, N, array);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
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
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT, const dummyT&, const dummyT
#endif
>::type const_reverse_iterator;
@ -247,7 +247,7 @@ main()
const dummyT* const_reversed = reversed;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
#endif
@ -282,7 +282,7 @@ main()
// 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)
#if defined(__SGI_STL_PORT) || !defined(__GNUC__) && !defined(__BORLANDC__) && (!defined(BOOST_MSVC) || BOOST_MSVC > 1200)
boost::const_nonconst_iterator_test(i, ++j);
#endif
}
@ -300,7 +300,7 @@ main()
typedef boost::detail::non_bidirectional_category<dummyT*>::type category;
typedef boost::filter_iterator_generator<one_or_four, dummyT*
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT
#endif
>::type filter_iter;
@ -327,7 +327,7 @@ main()
// 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)
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || defined(__SGI_STL_PORT)
std::deque<dummyT> array2;
std::copy(array+0, array+N, std::back_inserter(array2));
boost::forward_iterator_test(
@ -339,7 +339,7 @@ main()
dummyT(1), dummyT(4));
#endif
#if !defined(BOOST_MSVC) // This just freaks MSVC out completely
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 // This just freaks MSVC out completely
boost::forward_iterator_test(
boost::make_filter_iterator<one_or_four>(
boost::make_reverse_iterator(array2.end()),
@ -348,7 +348,7 @@ main()
dummyT(4), dummyT(1));
#endif
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
boost::forward_iterator_test(
boost::make_filter_iterator(array+0, array+N, one_or_four()),
dummyT(1), dummyT(4));

View File

@ -128,6 +128,8 @@
<a href="generator_iterator.htm">Generator Iterator Adaptor</a>
<li>Header <tt><a href="../../boost/permutation_iterator.hpp">boost/permutation_iterator.hpp</a></tt><br>
<a href="permutation_iterator.htm">Permutation Iterator Adaptor</a>
<li>Header <tt><a href="../../boost/shared_container_iterator.hpp">boost/shared_container_iterator.hpp</a></tt><br>
<a href="shared_container_iterator.html">Shared_Container Iterator Adaptor</a>
</ul>
<p><b><a href="../../people/dave_abrahams.htm">Dave
@ -156,6 +158,9 @@
adaptor.<br>
Toon Knapen contributed the <a href="permutation_iterator.htm">permutation
iterator</a> adaptor.<br>
<b><a href="../../people/ronald_garcia.htm">Ronald Garcia</a></b>
contributed the <a href="shared_container_iterator.html">shared container iterator</a>
adaptor.<br>
<h2><a name="iterator_adaptor">Class template</a>
<tt>iterator_adaptor</tt></h2>
@ -184,7 +189,7 @@ struct iterator_adaptor;
<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
you must supply in most cases, especially if <tt>Base</tt> is an
iterator.
<table border="1" summary="iterator_adaptor template parameters">
@ -193,17 +198,26 @@ struct iterator_adaptor;
<th>Description
<tr>
<td><tt>BaseType</tt>
<th>Requirements
<td>The type being wrapped.
<tr>
<td><tt>Base</tt>
<td>The data type on which the resulting iterator is based. Do
not be misled by the name &quot;Base&quot;: this is not a base
class.
<td>
<a href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>,
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default&nbsp;Constructible</a>
<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>.
class</a> that supplies core functionality to the resulting iterator.
<td>See table <a href="#policies">below</a>.
<tr>
<td><tt>Value</tt>
@ -214,7 +228,7 @@ struct iterator_adaptor;
"#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&lt;BaseType&gt;::value_type</tt> <a href=
<tt>std::iterator_traits&lt;Base&gt;::value_type</tt> <a href=
"#2">[2]</a>
<tr>
@ -224,29 +238,52 @@ struct iterator_adaptor;
particular, the result type of <tt>operator*()</tt>.<br>
<b>Default:</b> If <tt>Value</tt> is supplied, <tt>Value&amp;</tt> is
used. Otherwise
<tt>std::iterator_traits&lt;BaseType&gt;::reference</tt> is used. <a href="#7">[7]</a>
<tt>std::iterator_traits&lt;Base&gt;::reference</tt> is used. <a href="#7">[7]</a>
<td><a
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterators</a>,
<a
href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterators</a>,
and <a
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterators</a>
require that Reference is a true reference type (e.g. not a proxy).
<tr>
<td><tt>Pointer</tt>
<td>The <tt>pointer</tt> type of the resulting iterator, and in
particular, the result type of <tt>operator-&gt;()</tt>.<br>
<b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
otherwise <tt>std::iterator_traits&lt;BaseType&gt;::pointer</tt>. <a href="#7">[7]</a>
<b>Default:</b> If <tt>Value</tt> was not supplied, <tt>std::iterator_traits&lt;Base&gt;::pointer</tt>. <a
href="#7">[7]</a> Otherwise, if <code>iterator_category</code> is
<code>input_iterator</code>, then a class yielding
<tt>Value*</tt> when <code>operator-&gt;()</code> is applied.
Otherwise, <tt>Value*</tt>.
<td><code>value_type*</code> or a
class which yields <code>value_type*</code> when
<code>operator-&gt;()</code> is applied.
<tr>
<td><tt>Category</tt>
<td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
<b>Default:</b>
<tt>std::iterator_traits&lt;BaseType&gt;::iterator_category</tt>
<tt>std::iterator_traits&lt;Base&gt;::iterator_category</tt>
<td>One of
<code>std::input_iterator_tag</code>,
<code>std::output_iterator_tag</code>,
<code>std::forward_iterator_tag</code>,
<code>std::bidirectional_iterator_tag</code>, or
<code>std::random_access_iterator_tag</code>.
<tr>
<td><tt>Distance</tt>
<td>The <tt>difference_type</tt> for the resulting iterator.<br>
<b>Default:</b>
<tt>std::iterator_traits&lt;BaseType&gt;::difference_type</tt>
<tt>std::iterator_traits&lt;Base&gt;::difference_type</tt>
<td>A signed integral type
<tr>
<td><tt>NamedParam</tt>
@ -362,7 +399,7 @@ typedef iterator_adaptor&lt;foo_iterator, foo_policies,
<td>increments the iterator
<td><tt>++p</tt>, <tt>p++</tt>
<td><tt>++x</tt>, <tt>x++</tt>
<tr>
<td nowrap><tt>p.decrement(x)</tt>
@ -498,6 +535,15 @@ struct <a name="default_iterator_policies">default_iterator_policies</a>
Return a reference to the base object. This is to give the policies object
access to the base object. See <a href="#policies">above</a> for policies
iterator_adaptor interaction.<a href="#8">[8]</a>
<tr>
<td><tt>const Policies& policies() const;</tt>
<br><br>
Return a const reference to the policies object.
<tr> <td><tt>Policies& policies();</tt>
<br><br>
Return a reference to the policies object.
</table>
<h3><a name="example">Example</a></h3>
@ -515,7 +561,7 @@ struct <a name="default_iterator_policies">default_iterator_policies</a>
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>
"http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>
is the <a href="../../more/generic_programming.html#concept">Concept</a>
that fulfills those requirements.

View File

@ -85,15 +85,17 @@ template <class Iterator,
struct non_portable_tests
{
// Unfortunately, the VC6 standard library doesn't supply these :(
typedef typename boost::detail::iterator_traits<Iterator>::pointer test_pt;
typedef typename boost::detail::iterator_traits<Iterator>::reference test_rt;
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::pointer,
::boost::is_same<
test_pt,
pointer
>::value));
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::reference,
::boost::is_same<
test_rt,
reference
>::value));
};
@ -102,15 +104,17 @@ template <class Iterator,
class value_type, class difference_type, class pointer, class reference, class category>
struct portable_tests
{
typedef typename boost::detail::iterator_traits<Iterator>::difference_type test_dt;
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category test_cat;
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::difference_type,
::boost::is_same<
test_dt,
difference_type
>::value));
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::iterator_category,
::boost::is_same<
test_cat,
category
>::value));
};
@ -121,9 +125,10 @@ template <class Iterator,
struct input_iterator_test
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
{
typedef typename boost::detail::iterator_traits<Iterator>::value_type test_vt;
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::value_type,
::boost::is_same<
test_vt,
value_type
>::value));
};

View File

@ -347,7 +347,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

View File

@ -569,7 +569,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);

View File

@ -12,7 +12,7 @@ int main(int, char*[])
{
char letters_[] = "hello world!";
const int N = sizeof(letters_)/sizeof(char) - 1;
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
// Assume there won't be proper iterator traits for pointers. This
// is just a wrapper for char* which has the right traits.
typedef boost::iterator_adaptor<char*, boost::default_iterator_policies, char> base_iterator;

View File

@ -0,0 +1,332 @@
<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="../../c++boost.gif" alt="c++boost.gif (8819 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 be deleted after the last iterator is destroyed.
The shared container iterator is typically used to implement functions
that return iterators over a
range of objects that will only be needed for the lifetime of
the iterators. By returning a pair of shared iterators from a
function, the callee can ensure that the underlying container's
lifetime will be properly managed.
<p>
The shared container iterator augments an iterator into a shared
container with a reference counted pointer to the container.
Assuming no other references exist to the container, it will be
destroyed when the last shared container iterator is destroyed.
In all other ways, the shared container iterator
behaves the same as its base iterator.
<h2>Synopsis</h2>
<pre>
namespace boost {
template &lt;typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>&gt;
class shared_container_iterator_generator;
template &lt;typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>&gt;
typename shared_container_iterator_generator&lt;Container&gt;::type
make_shared_container_iterator(typename Container::iterator base,
boost::shared_ptr&lt;Container&gt; const&amp; container);
std::pair&lt
typename shared_container_iterator_generator&lt;Container&gt;::type,
typename shared_container_iterator_generator&lt;Container&gt;::type
&gt;
make_shared_container_range(boost::shared_ptr&lt;Container&gt; const&amp; container);
}
</pre>
<hr>
<h2><a name="generator">The Shared Container Iterator Type Generator</a></h2>
The class <tt>shared_container_iterator_generator</tt> is a helper
class to construct a shared container iterator type. The template
parameter for this class is a type that models the
<a href="http://www.sgi.com/tech/stl/Container.html">Container</a>
concept.
<pre>
template &lt;typename Container&gt;
class shared_container_iterator_generator
{
public:
typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt;...&gt; type;
};
</pre>
<h3>Example</h3>
<p>
The following example illustrates how to use the
<tt>shared_counter_iterator_generator</tt> to create an iterator that
regulates the lifetime of a reference counted <tt>std::vector</tt>.
Though the original <tt>shared_ptr</tt> to the vector ceases to exist, the
<tt>shared_counter_iterator</tt>s extend the lifetime of the container.
<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 &lt;algorithm&gt;</font>
<font color="#008040">#include &lt;iostream&gt;</font>
<font color="#008040">#include &lt;vector&gt;</font>
<B>typedef</B> boost::shared_container_iterator_generator&lt; std::vector&lt;<B>int</B>&gt; &gt;::type iterator;
<B>void</B> set_range(iterator& i, iterator& end) {
boost::shared_ptr&lt; std::vector&lt;<B>int</B>&gt; &gt; ints(<B>new</B> std::vector&lt;<B>int</B>&gt;());
ints-&gt;push_back(<font color="#0000A0">0</font>);
ints-&gt;push_back(<font color="#0000A0">1</font>);
ints-&gt;push_back(<font color="#0000A0">2</font>);
ints-&gt;push_back(<font color="#0000A0">3</font>);
ints-&gt;push_back(<font color="#0000A0">4</font>);
ints-&gt;push_back(<font color="#0000A0">5</font>);
i = iterator(ints-&gt;begin(),ints);
end = iterator(ints-&gt;end(),ints);
}
<B>int</B> main() {
iterator i,end;
set_range(i,end);
std::copy(i,end,std::ostream_iterator&lt;<B>int</B>&gt;(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 shared container iterator adaptor (the type
<tt>shared_container_iterator_generator<...>::type</tt>) models the
same iterator concept as the base iterator
(<tt>Container::iterator</tt>) up to
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
Access Iterator</a>.
<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_generator::type(Container::iterator const&amp; it,
boost::shared_ptr&lt;Container&gt; const&amp; container)
</pre>
<p>
<hr>
<p>
<h2><a name="make_iterator">The Shared Container Iterator Object Generator</a></h2>
<pre>
template &lt;typename Container&gt;
typename shared_container_iterator_generator&lt;AdaptableUnaryFunction,BaseIterator&gt;::type
make_shared_container_iterator(Container::iterator base,
boost::shared_ptr&lt;Container&gt; const&amp; container)
</pre>
This function provides an alternative to using the shared container
iterator type generator to create the iterator type before
construction. 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 &lt;algorithm&gt;</font>
<font color="#008040">#include &lt;iterator&gt;</font>
<font color="#008040">#include &lt;iostream&gt;</font>
<font color="#008040">#include &lt;vector&gt;</font>
<B>template</B> &lt;<B>typename</B> Iterator&gt;
<B>void</B> print_range_nl (Iterator begin, Iterator end) {
<B>typedef</B> <B>typename</B> std::iterator_traits&lt;Iterator&gt;::value_type val;
std::copy(begin,end,std::ostream_iterator&lt;val&gt;(std::cout,<font color="#0000FF">","</font>));
std::cout.put(<font color="#0000FF">'\n'</font>);
}
<B>int</B> main() {
<B>typedef</B> boost::shared_ptr&lt; std::vector&lt;<B>int</B>&gt; &gt; ints_t;
{
ints_t ints(<B>new</B> std::vector&lt;<B>int</B>&gt;());
ints-&gt;push_back(<font color="#0000A0">0</font>);
ints-&gt;push_back(<font color="#0000A0">1</font>);
ints-&gt;push_back(<font color="#0000A0">2</font>);
ints-&gt;push_back(<font color="#0000A0">3</font>);
ints-&gt;push_back(<font color="#0000A0">4</font>);
ints-&gt;push_back(<font color="#0000A0">5</font>);
print_range_nl(boost::make_shared_container_iterator(ints-&gt;begin(),ints),
boost::make_shared_container_iterator(ints-&gt;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 &lt;typename Container&gt;
std::pair&lt
typename shared_container_iterator_generator&lt;Container&gt;::type,
typename shared_container_iterator_generator&lt;Container&gt;::type
&gt;
make_shared_container_range(boost::shared_ptr&lt;Container&gt; const&amp; container);
</pre>
Class <tt>shared_container_iterator</tt> is meant primarily to return
via 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. This function is equivalent to
<pre>
std::make_pair(make_shared_container_iterator(container-&gt;begin(),container),
make_shared_container_iterator(container-&gt;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>s.
<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 &lt;algorithm&gt; // for std::copy</font>
<font color="#008040">#include &lt;iostream&gt; </font>
<font color="#008040">#include &lt;vector&gt;</font>
<B>typedef</B> boost::shared_container_iterator_generator&lt; std::vector&lt;<B>int</B>&gt; &gt;::type
function_iterator;
std::pair&lt;function_iterator,function_iterator&gt;
return_range() {
boost::shared_ptr&lt; std::vector&lt;<B>int</B>&gt; &gt; range(<B>new</B> std::vector&lt;<B>int</B>&gt;());
range-&gt;push_back(<font color="#0000A0">0</font>);
range-&gt;push_back(<font color="#0000A0">1</font>);
range-&gt;push_back(<font color="#0000A0">2</font>);
range-&gt;push_back(<font color="#0000A0">3</font>);
range-&gt;push_back(<font color="#0000A0">4</font>);
range-&gt;push_back(<font color="#0000A0">5</font>);
<B>return</B> boost::make_shared_container_range(range);
}
<B>int</B> main() {
function_iterator i,end;
boost::tie(i,end) = return_range();
std::copy(i,end,std::ostream_iterator&lt;<B>int</B>&gt;(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: Wed Sep 4 15:52:17 EST 2002
<!-- hhmts end -->
<p><EFBFBD> Copyright Ronald Garcia 2002. Permission to copy, use,
modify, sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided &quot;as is&quot;
without express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
</body>
</html>

View File

@ -0,0 +1,42 @@
// (C) Copyright Ronald Garcia 2002. 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/shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <algorithm>
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator_generator< std::vector<int> >::type
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;
}

View File

@ -0,0 +1,42 @@
// (C) Copyright Ronald Garcia 2002. 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/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;
}

View File

@ -0,0 +1,41 @@
// (C) Copyright Ronald Garcia 2002. 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/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_generator< std::vector<int> >::type
function_iterator;
std::pair<function_iterator,function_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() {
function_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;
}

View File

@ -19,6 +19,7 @@
#include <set>
#include <algorithm>
#include <iostream>
#include <iterator> // std::distance
// Note: tie() use to live in boost/utility.hpp, but
// not it is part of the more general Boost Tuple Library.
#include <boost/tuple/tuple.hpp>

View File

@ -19,7 +19,7 @@ Defined in header
<p>
The transform iterator adaptor augments an iterator by applying some
function object to the result of dereferencing the iterator. Another
function object to the result of dereferencing the iterator. In other
words, the <tt>operator*</tt> of the transform iterator first
dereferences the base iterator, passes the result of this to the
function object, and then returns the result. The following

View File

@ -22,6 +22,7 @@
checked_array_delete()</a></li>
<li>Function templates <a href="#functions next">next() and prior()</a></li>
<li>Class <a href="#Class noncopyable">noncopyable</a></li>
<li>Function template <a href="#addressof">addressof()</a></li>
<li>Function template <a href="tie.html">tie()</a> and supporting class tied.</li>
</ul>
<h2> Function templates <a name="checked_delete">checked_delete</a>() and
@ -133,6 +134,48 @@ emphasize that it is to be used only as a base class.&nbsp; Dave Abrahams notes
concern about the effect on compiler optimization of adding (even trivial inline)
destructor declarations. He says &quot;Probably this concern is misplaced, because
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics.&quot;</p>
<h2><a name="addressof">Function template addressof()</a></h2>
<p>Function <strong>addressof()</strong> returns the address of an object.</p>
<blockquote>
<pre>
template &lt;typename T&gt; inline T* addressof(T& v);
template &lt;typename T&gt; inline const T* addressof(const T& v);
template &lt;typename T&gt; inline volatile T* addressof(volatile T& v);
template &lt;typename T&gt; inline const volatile T* addressof(const volatile T& v);
</pre>
</blockquote>
<p>C++ allows programmers to replace the unary
<strong>operator&()</strong> class member used to get the address of
an object. Getting the real address of an object requires ugly
casting tricks to avoid invoking the overloaded
<strong>operator&()</strong>. Function <strong>addressof()</strong>
provides a wrapper around the necessary code to make it easy to get an
object's real address.
</p>
<p>The program <a href="addressof_test.cpp">addressof_test.cpp</a> can be
used to verify that <b>addressof()</b> works as expected.</p>
<p>Contributed by Brad King based on ideas from discussion with Doug Gregor.</p>
<h3>Example</h3>
<blockquote>
<pre>#include &lt;boost/utility.hpp&gt;
struct useless_type {};
class nonaddressable {
useless_type operator&() const;
};
void f() {
nonaddressable x;
nonaddressable* xp = boost::addressof(x);
// nonaddressable* xpe = &amp;x; /* error */
}</pre>
</blockquote>
<h2>Class templates for the Base-from-Member Idiom</h2>
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
<h2>Function template tie()</h2>

219
value_init.htm Normal file
View File

@ -0,0 +1,219 @@
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>value_initialized</title>
</head>
<body vlink="#800080" link="#0000ff" text="#000000" bgcolor="#ffffff">
<h2><img src="../../c++boost.gif" width="276" height="86">
Header &lt;<a href="../../boost/utility/value_init.hpp">boost/utility/value_init.hpp</a>&gt;
</h2>
<h2>Contents</h2>
<dl>
<dt><a href="#intro">Rationale</a></dt>
<dt><a href="#rationale">Introduction</a></dt>
</dl>
<ul>
<li><a href="#valueinit">value-initialization</a></li>
<li><a href="#valueinitsyn">value-initialization syntax</a></li>
</ul>
<dl class="page-index">
<dt><a href="#types">Types</a></dt>
</dl>
<ul>
<li><a href="#val_init"><code>value_initialized&lt;&gt;</code></a></li>
</ul>
<a href="#acknowledgements">Acknowledgements</a><br>
<br>
<hr>
<h2><a name="rationale"></a>Rationale</h2>
<p>Constructing and initializing objects in a generic way is difficult in
C++. The problem is that there are several different rules that apply
for initialization. Depending on the type, the value of a newly constructed
object can be zero-initialized (logically 0), default-constructed (using
the default constructor), or indeterminate. When writing generic code,
this problem must be addressed. <code>value_initialized</code> provides
a solution with consistent syntax for value initialization of scalar,
union and class types. <br>
</p>
<h2><a name="into"></a>Introduction</h2>
<p>The C++ standard [<a href="#references">1</a>] contains the definitions
of <code>zero-initialization</code> and <code>default-initialization</code>.
Informally, zero-initialization means that the object is given the initial
value 0 (converted to the type) and default-initialization means that
POD [<a href="#references">2</a>] types are zero-initialized, while class
types are initialized with their corresponding default constructors. A
<i>declaration</i> can contain an <i>initializer</i>, which specifies the
object's initial value. The initializer can be just '()', which states that
the object shall be default-initialized (but see below). However, if a <i>declaration</i>
has no <i>initializer</i> and it is of a non-<code>const</code>, non-<code>static</code>
POD type, the initial value is indeterminate:<cite>(see &sect;8.5 for the
accurate definitions).</cite></p>
<pre>int x ; // no initializer. x value is indeterminate.<br>std::string s ; // no initializer, s is default-constructed.<br><br>int y = int() ; <br>// y is initialized using copy-initialization<br>// but the temporary uses an empty set of parentheses as the initializer,<br>// so it is default-constructed.<br>// A default constructed POD type is zero-initialized,<br>// therefore, y == 0.<br><br>void foo ( std::string ) ;<br>foo ( std::string() ) ; <br>// the temporary string is default constructed <br>// as indicated by the initializer () </pre>
<h3><a name="valueinit">value-initialization</a></h3>
<p>The first <a
href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_defects.html">Technical
Corrigendum for the C++ Standard</a> (TC1), whose draft was released to
the public in November 2001, introduced <a
href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_defects.html#178">Core
Issue 178</a> (among many other issues, of course).</p>
<p> That issue introduced the new concept of <code>value-initialization</code>
(it also fixed the wording for zero-initialization). Informally, value-initialization
is similar to default-initialization with the exception that in some cases
non-static data members and base class sub-objects are also value-initialized.
The difference is that an object that is value-initialized won't have
(or at least is less likely to have) indeterminate values for data members
and base class sub-objects; unlike the case of an object default constructed.
(see Core Issue 178 for a normative description).</p>
<p>In order to specify value-initialization of an object we need to use the
empty-set initializer: (). </p>
<p><i>(but recall that the current C++ Standard states that '()' invokes default-initialization,
not value-initialization)</i></p>
<p>As before, a declaration with no intializer specifies default-initialization,
and a declaration with a non-empty initializer specifies copy (=xxx) or
direct (xxx) initialization. </p>
<pre>template&lt;class T&gt; void eat(T);<br>int x ; // indeterminate initial value.<br>std::string s; // default-initialized.<br>eat ( int() ) ; // value-initialized<br>eat ( std::string() ) ; // value-initialied</pre>
<h4><a name="valueinitsyn">value-initialization</a> syntax</h4>
<p>Value initialization is specified using (). However, the empty set of
parentheses is not permitted by the syntax of initializers because it is
parsed as the declaration of a function taking no arguments: </p>
<pre>int x() ; // declares function int(*)()<br>int y ( int() ) ; // decalares function int(*)( int(*)() )</pre>
<p>Thus, the empty () must be put in some other initialization context.</p>
<p>One alternative is to use copy-initialization syntax:</p>
<pre>int x = int() ;</pre>
<p>This works perfectly fine for POD types. But for non-POD class types,
copy-initialization searches for a suitable constructor, which could be,
for instance, the copy-constructor (it also searches for a suitable conversion
sequence but this doesn't apply in this context). For an arbitrary unknown
type, using this syntax may not have the value-initialization effect intended
because we don't know if a copy from a default constructed object is exactly
the same as a default constructed object, and the compiler is allowed (in
some cases), but never required to, optimize the copy away.</p>
<p>One possible generic solution is to use value-initialization of a non static
data member:</p>
<pre>template&lt;class T&gt; <br>struct W <br>{<br> // value-initialization of 'data' here.<br> W() : data() {}<br> T data ;<br>} ;<br>W&lt;int&gt; w ;<br>// w.data is value-initialized for any type. </pre>
<p><code>This is the solution supplied by the value_initialized&lt;&gt; template
class.</code></p>
<h2><a name="types"></a>Types</h2>
<h2><a name="val_init"><code>template class value_initialized&lt;T&gt;</code></a></h2>
<pre>namespace boost {<br><br>template&lt;class T&gt;<br>class value_initialized<br>{<br> public :<br> value_initialized() : x() {}<br> operator T&amp;() const { return x ; }<br> T&amp; data() const { return x ; }<br><br> private :<br> <i>impll-defined</i> x ;<br>} ;<br><br>template&lt;class T&gt;<br>T const&amp; get ( value_initialized&lt;T&gt; const&amp; x )<br>{<br> return x.data() ;<br>}<br><br>template&lt;class T&gt;<br>T&amp; get ( value_initialized&lt;T&gt;&amp; x )<br>{<br> return x.data() ;<br>}<br><br>} // namespace boost<br></pre>
<p>An object of this template class is a <code>T</code>-wrapper convertible
to <code>'T&amp;'</code> whose wrapped object (data member of type <code>T</code>)
is <a href="#valueinit">value-initialized</a> upon default-initialization
of this wrapper class: </p>
<pre>int zero = 0 ;<br>value_initialized&lt;int&gt; x ;<br>assert ( x == zero ) ;<br><br>std::string def ;<br>value_initialized&lt; std::string &gt; y ;<br>assert ( y == def ) ;<br></pre>
<p>The purpose of this wrapper is to provide a consistent syntax for value
initialization of scalar, union and class types (POD and non-POD) since
the correct syntax for value initialization varies (see <a
href="#valueinitsyn">value-initialization syntax</a>)</p>
<p>The wrapped object can be accessed either through the conversion operator
<code>T&amp;</code>, the member function <code>data()</code>, or the
non-member function <code>get()</code>: </p>
<pre>void watch(int);<br>value_initialized&lt;int&gt; x;<br><br>watch(x) ; // operator T&amp; used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
<p>Both <code>const</code> and non-<code>const</code> objects can be wrapped.
Mutable objects can be modified directly from within the wrapper but constant
objects cannot:</p>
<pre>value_initialized&lt;int&gt; x ; <br>static_cast&lt;int&amp;&gt;(x) = 1 ; // OK<br>get(x) = 1 ; // OK<br><br>value_initialized&lt;int const&gt; y ; <br>static_cast&lt;int&amp;&gt;(y) = 1 ; // ERROR: cannot cast to int&amp;<br>static_cast&lt;int const&amp;&gt;(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
<h3>Warning:</h3>
<p>Both the conversion operator and the <code>data()</code> member function
are <code>const</code> in order to allow access to the wrapped object
from a constant wrapper:</p>
<pre>void foo(int);<br>value_initialized&lt;int&gt; const x ;<br>foo(x);<br></pre>
<p>But notice that this conversion operator is to <code>T&amp;</code> although
it is itself <code>const</code>. As a consequence, if <code>T</code> is
a non-<code>const</code> type, you can modify the wrapped object even from
within a constant wrapper:</p>
<pre>value_initialized&lt;int&gt; const x_c ;<br>int&amp; xr = x_c ; // OK, conversion to int&amp; available even though x_c is itself const.<br>xr = 2 ; </pre>
<p>The reason for this obscure behavior is that some commonly used compilers
just don't accept the following valid code:</p>
<pre>struct X<br>{<br> operator int&amp;() ;<br> operator int const&amp;() const ; <br>};<br>X x ;<br>(x == 1 ) ; // ERROR HERE!</pre>
<p>These compilers complain about ambiguity between the conversion operators.
This complaint is incorrect, but the only workaround that I know of is
to provide only one of them, which leads to the obscure behavior just explained.<br>
</p>
<h3>Recommended practice: The non-member get() idiom</h3>
<p>The obscure behavior of being able to modify a non-<code>const</code>
wrapped object from within a constant wrapper can be avoided if access to
the wrapped object is always performed with the <code>get()</code> idiom:</p>
<pre>value_initialized&lt;int&gt; x ;<br>get(x) = 1 ; // OK<br><br>value_initialized&lt;int const&gt; cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int&gt; const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int const&gt; const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
<h3><a name="references">References</a></h3>
[1] The C++ Standard, ISO/IEC 14882:98 <br>
[2] Plain Old Data
<h3><a name="acknowledgements"></a>Acknowledgements</h3>
value_initialized was developed by Fernando Cacciola, with help and
suggestions from David Abrahams and Darin Adler.<br>
Special thanks to Bj<42>rn Karlsson who carefully edited and completed this documentation.
<pre>&nbsp;</pre>
<hr>
<p>Revised 19 September 2002</p>
<p>&copy; Copyright boost.org 2002. 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>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 discussion list
at <a href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.
</p>
<br>
<br>
</body>
</html>

119
value_init_test.cpp Normal file
View File

@ -0,0 +1,119 @@
// (C) 2002, Fernando Luis Cacciola Carballal.
//
// This material is provided "as is", with absolutely no warranty expressed
// or implied. Any use is at your own risk.
//
// Permission to use or copy this software for any purpose is hereby granted
// without fee, provided the above notices are retained on all copies.
// Permission to modify the code and to distribute modified code is granted,
// provided the above notices are retained, and a notice that the code was
// modified is included with the above copyright notice.
//
// Test program for "boost/utility/value_init.hpp"
//
// Initial: 21 Agu 2002
#include <iostream>
#include <string>
#include "boost/utility/value_init.hpp"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#define BOOST_INCLUDE_MAIN
#include "boost/test/test_tools.hpp"
//
// Sample POD type
//
struct POD
{
POD () : c(0), i(0), f(0) {}
POD ( char c_, int i_, float f_ ) : c(c_), i(i_), f(f_) {}
friend std::ostream& operator << ( std::ostream& os, POD const& pod )
{ return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; }
friend bool operator == ( POD const& lhs, POD const& rhs )
{ return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
float f;
char c;
int i;
} ;
//
// Sample non POD type
//
struct NonPODBase
{
virtual ~NonPODBase() {}
} ;
struct NonPOD : NonPODBase
{
NonPOD () : id() {}
NonPOD ( std::string const& id_) : id(id_) {}
friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod )
{ return os << '(' << npod.id << ')' ; }
friend bool operator == ( NonPOD const& lhs, NonPOD const& rhs )
{ return lhs.id == rhs.id ; }
std::string id ;
} ;
template<class T>
void test ( T const& y, T const& z )
{
boost::value_initialized<T> x ;
BOOST_TEST ( y == x ) ;
BOOST_TEST ( y == get(x) ) ;
static_cast<T&>(x) = z ;
get(x) = z ;
BOOST_TEST ( x == z ) ;
boost::value_initialized<T> const x_c ;
BOOST_TEST ( y == x_c ) ;
BOOST_TEST ( y == get(x_c) ) ;
static_cast<T&>(x_c) = z ;
BOOST_TEST ( x_c == z ) ;
#ifdef PRODUCE_ERROR_1
get(x_c) = z ; // this should produce an ERROR
#endif
boost::value_initialized<T const> cx ;
BOOST_TEST ( y == cx ) ;
BOOST_TEST ( y == get(cx) ) ;
#ifdef PRODUCE_ERROR_2
get(cx) = z ; // this should produce an ERROR
#endif
boost::value_initialized<T const> const cx_c ;
BOOST_TEST ( y == cx_c ) ;
BOOST_TEST ( y == get(cx_c) ) ;
#ifdef PRODUCE_ERROR_3
get(cx_c) = z ; // this should produce an ERROR
#endif
}
int test_main(int, char **)
{
test( 0,1234 ) ;
test( 0.0,12.34 ) ;
test( POD(0,0,0.0), POD('a',1234,56.78) ) ;
test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ;
return 0;
}
unsigned int expected_failures = 0;