mirror of
https://github.com/boostorg/utility.git
synced 2025-10-06 14:00:55 +02:00
Compare commits
1 Commits
boost-1.30
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
cfb38f7097 |
648
Collection.html
648
Collection.html
@@ -1,648 +0,0 @@
|
|||||||
<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 "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>
|
|
@@ -1,130 +0,0 @@
|
|||||||
<HTML>
|
|
||||||
<Head>
|
|
||||||
<Title>OptionalPointee Concept</Title>
|
|
||||||
</HEAD>
|
|
||||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
|
||||||
ALINK="#ff0000">
|
|
||||||
<IMG SRC="../../c++boost.gif"
|
|
||||||
ALT="C++ Boost" width="277" height="86">
|
|
||||||
<!--end header-->
|
|
||||||
<BR Clear>
|
|
||||||
<H1>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 a <i>deep</i> equality-test that can
|
|
||||||
be used in generic code with any type which models OptionalPointee:</p>
|
|
||||||
<a name="equal"></a>
|
|
||||||
<pre>
|
|
||||||
template<class OptionalPointee>
|
|
||||||
inline
|
|
||||||
bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y )
|
|
||||||
{
|
|
||||||
return (!x) != (!y) ? false : ( !x ? true : (*x) == (*y) ) ;
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
<p>The preceding generic function has the following semantics:<br>
|
|
||||||
If both x and y have valid pointees, it compares pointee's values via (*x == *y).<br>
|
|
||||||
If only one has a valid pointee, returns false.<br>
|
|
||||||
If both have invalid pointees, returns true.</p>
|
|
||||||
<p><code>equal_pointees()</code> is implemented in <a href="../../boost/optional.hpp">optional.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>
|
|
57
assert.html
57
assert.html
@@ -1,57 +0,0 @@
|
|||||||
<!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="../../c++boost.gif" alt="c++boost.gif (8819 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>
|
|
@@ -1,3 +1,10 @@
|
|||||||
|
#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
|
||||||
|
|
||||||
//
|
//
|
||||||
// assert_test.cpp - a test for boost/assert.hpp
|
// assert_test.cpp - a test for boost/assert.hpp
|
||||||
//
|
//
|
||||||
@@ -9,97 +16,18 @@
|
|||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#define BOOST_DEBUG 1
|
||||||
|
|
||||||
#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/assert.hpp>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
int handler_invoked = 0;
|
bool boost_error(char const * expr, char const * func, char const * file, long line)
|
||||||
|
|
||||||
void boost::assertion_failed(char const * expr, char const * function, char const * file, long line)
|
|
||||||
{
|
{
|
||||||
std::printf("Expression: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", expr, function, file, line);
|
std::printf("%s(%ld): Assertion '%s' failed in function '%s'\n", file, line, expr, func);
|
||||||
++handler_invoked;
|
return true; // fail w/ standard assert()
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
int main()
|
||||||
{
|
{
|
||||||
test_default();
|
BOOST_ASSERT(0 == 1);
|
||||||
test_disabled();
|
|
||||||
test_handler();
|
|
||||||
|
|
||||||
return boost::report_errors();
|
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include <boost/config.hpp> // for BOOST_NO_MEMBER_TEMPLATES
|
#include <boost/config.hpp> // for BOOST_NO_MEMBER_TEMPLATES
|
||||||
#include <boost/cstdlib.hpp> // for boost::exit_success
|
#include <boost/cstdlib.hpp> // for boost::exit_success
|
||||||
#include <boost/noncopyable.hpp> // for boost::noncopyable
|
#include <boost/utility.hpp> // for boost::noncopyable
|
||||||
|
|
||||||
#include <boost/utility/base_from_member.hpp> // for boost::base_from_member
|
#include <boost/utility/base_from_member.hpp> // for boost::base_from_member
|
||||||
|
|
||||||
|
@@ -120,7 +120,7 @@ void random_sorted_sequence(std::list<std::string>& result)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template <>
|
template <>
|
||||||
void sort_by_value(std::list<std::string>& l)
|
inline void sort_by_value(std::list<std::string>& l)
|
||||||
{
|
{
|
||||||
l.sort(cmp());
|
l.sort(cmp());
|
||||||
}
|
}
|
||||||
|
@@ -408,7 +408,7 @@ template struct call_traits_test<int[2], true>;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_MSVC) && _MSC_VER <= 1300
|
#ifdef BOOST_MSVC
|
||||||
unsigned int expected_failures = 14;
|
unsigned int expected_failures = 14;
|
||||||
#elif defined(__SUNPRO_CC)
|
#elif defined(__SUNPRO_CC)
|
||||||
#if(__SUNPRO_CC <= 0x520)
|
#if(__SUNPRO_CC <= 0x520)
|
||||||
|
@@ -1,124 +0,0 @@
|
|||||||
<!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="../../c++boost.gif" alt="c++boost.gif (8819 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>
|
|
@@ -11,7 +11,7 @@
|
|||||||
// Revision History
|
// Revision History
|
||||||
// 21 May 01 Initial version (Beman Dawes)
|
// 21 May 01 Initial version (Beman Dawes)
|
||||||
|
|
||||||
#include <boost/checked_delete.hpp> // for checked_delete
|
#include <boost/utility.hpp> // for checked_delete
|
||||||
|
|
||||||
// This program demonstrates compiler errors when trying to delete an
|
// This program demonstrates compiler errors when trying to delete an
|
||||||
// incomplete type.
|
// incomplete type.
|
||||||
|
269
counting_iterator_test.cpp
Normal file
269
counting_iterator_test.cpp
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
// (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>
|
||||||
|
#ifndef __BORLANDC__
|
||||||
|
# include <boost/tuple/tuple.hpp>
|
||||||
|
#endif
|
||||||
|
#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));
|
||||||
|
|
||||||
|
// #including tuple crashed borland, so I had to give up on tie().
|
||||||
|
std::pair<CountingIterator,CountingIterator> xy(
|
||||||
|
std::equal_range(start, finish, *internal));
|
||||||
|
CountingIterator x = xy.first, y = xy.second;
|
||||||
|
|
||||||
|
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(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) || BOOST_MSVC > 1200 || 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;
|
||||||
|
}
|
@@ -1,38 +0,0 @@
|
|||||||
<!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="../../c++boost.gif" alt="c++boost.gif (8819 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>
|
|
@@ -105,7 +105,7 @@ types.
|
|||||||
<pre>
|
<pre>
|
||||||
template <class Generator>
|
template <class Generator>
|
||||||
typename generator_iterator_generator<Generator>::type
|
typename generator_iterator_generator<Generator>::type
|
||||||
make_generator_iterator(Generator & gen);
|
make_function_output_iterator(Generator & gen);
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@@ -1,5 +1,12 @@
|
|||||||
|
#ifndef BOOST_ASSERT_HPP_INCLUDED
|
||||||
|
#define BOOST_ASSERT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1020
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// boost/assert.hpp - BOOST_ASSERT(expr)
|
// boost/assert.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||||
//
|
//
|
||||||
@@ -8,31 +15,38 @@
|
|||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
// Note: There are no include guards. This is intentional.
|
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/libs/utility/assert.html for documentation.
|
// When BOOST_DEBUG is not defined, it defaults to 0 (off)
|
||||||
|
// for compatibility with programs that do not expect asserts
|
||||||
|
// in the smart pointer class templates.
|
||||||
|
//
|
||||||
|
// This default may be changed after an initial transition period.
|
||||||
//
|
//
|
||||||
|
|
||||||
#undef BOOST_ASSERT
|
#ifndef BOOST_DEBUG
|
||||||
|
#define BOOST_DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_DISABLE_ASSERTS)
|
#if BOOST_DEBUG
|
||||||
|
|
||||||
# define BOOST_ASSERT(expr) ((void)0)
|
#include <assert.h>
|
||||||
|
|
||||||
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
|
#ifndef BOOST_ASSERT
|
||||||
|
|
||||||
#include <boost/current_function.hpp>
|
#include <boost/current_function.hpp>
|
||||||
|
|
||||||
namespace boost
|
bool boost_error(char const * expr, char const * func, char const * file, long line);
|
||||||
{
|
|
||||||
|
|
||||||
void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
|
# define BOOST_ASSERT(expr) ((expr) || !boost_error(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__) || (assert(expr), true))
|
||||||
|
|
||||||
} // namespace boost
|
#endif // #ifndef BOOST_ASSERT
|
||||||
|
|
||||||
#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
#else // #if BOOST_DEBUG
|
||||||
|
|
||||||
#else
|
#undef BOOST_ASSERT
|
||||||
# include <assert.h>
|
#define BOOST_ASSERT(expr) ((void)0)
|
||||||
# define BOOST_ASSERT(expr) assert(expr)
|
|
||||||
#endif
|
#endif // #if BOOST_DEBUG
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_ASSERT_HPP_INCLUDED
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
// in all copies. This software is provided "as is" without express or implied
|
// 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.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility/call_traits.htm for 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
|
// See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp
|
||||||
// for full copyright notices.
|
// for full copyright notices.
|
||||||
|
|
||||||
|
@@ -1,39 +1,35 @@
|
|||||||
#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
|
#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
|
||||||
#define BOOST_CHECKED_DELETE_HPP_INCLUDED
|
#define BOOST_CHECKED_DELETE_HPP_INCLUDED
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
#if _MSC_VER >= 1020
|
||||||
# pragma once
|
#pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// boost/checked_delete.hpp
|
// boost/checked_delete.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 1999, 2000, 2001, 2002 boost.org
|
// Copyright (c) 1999, 2000, 2001, 2002 boost.org
|
||||||
// Copyright (c) 2002, 2003 Peter Dimov
|
|
||||||
//
|
//
|
||||||
// Permission to copy, use, modify, sell and distribute this software
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
// is granted provided this copyright notice appears in all copies.
|
// is granted provided this copyright notice appears in all copies.
|
||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/libs/utility/checked_delete.html for documentation.
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
// verify that types are complete for increased safety
|
// verify that types are complete for increased safety
|
||||||
|
|
||||||
template<class T> inline void checked_delete(T * x)
|
template< typename T > inline void checked_delete(T * x)
|
||||||
{
|
{
|
||||||
// Intel 7 accepts sizeof(incomplete) as 0 in system headers
|
typedef char type_must_be_complete[sizeof(T)];
|
||||||
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
|
|
||||||
delete x;
|
delete x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline void checked_array_delete(T * x)
|
template< typename T > inline void checked_array_delete(T * x)
|
||||||
{
|
{
|
||||||
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
|
typedef char type_must_be_complete[sizeof(T)];
|
||||||
delete [] x;
|
delete [] x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +38,9 @@ template<class T> struct checked_deleter
|
|||||||
typedef void result_type;
|
typedef void result_type;
|
||||||
typedef T * argument_type;
|
typedef T * argument_type;
|
||||||
|
|
||||||
void operator()(T * x) const
|
void operator()(T * x)
|
||||||
{
|
{
|
||||||
// boost:: disables ADL
|
checked_delete(x);
|
||||||
boost::checked_delete(x);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,9 +49,9 @@ template<class T> struct checked_array_deleter
|
|||||||
typedef void result_type;
|
typedef void result_type;
|
||||||
typedef T * argument_type;
|
typedef T * argument_type;
|
||||||
|
|
||||||
void operator()(T * x) const
|
void operator()(T * x)
|
||||||
{
|
{
|
||||||
boost::checked_array_delete(x);
|
checked_array_delete(x);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -15,8 +15,6 @@
|
|||||||
// This software is provided "as is" without express or implied
|
// This software is provided "as is" without express or implied
|
||||||
// warranty, and with no claim as to its suitability for any purpose.
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
//
|
//
|
||||||
// http://www.boost.org/libs/utility/current_function.html
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -27,7 +25,7 @@ namespace detail
|
|||||||
inline void current_function_helper()
|
inline void current_function_helper()
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000))
|
#if defined(__GNUC__)
|
||||||
|
|
||||||
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
|
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
|
||||||
|
|
||||||
@@ -35,7 +33,7 @@ inline void current_function_helper()
|
|||||||
|
|
||||||
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
|
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
|
||||||
|
|
||||||
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
|
#elif defined(__BORLANDC__)
|
||||||
|
|
||||||
# define BOOST_CURRENT_FUNCTION __FUNC__
|
# define BOOST_CURRENT_FUNCTION __FUNC__
|
||||||
|
|
||||||
|
@@ -9,8 +9,6 @@
|
|||||||
// 15 Nov 2001 Jens Maurer
|
// 15 Nov 2001 Jens Maurer
|
||||||
// created.
|
// created.
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation.
|
|
||||||
|
|
||||||
#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
||||||
#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
||||||
|
|
||||||
|
@@ -1,33 +0,0 @@
|
|||||||
// Boost next_prior.hpp header file ---------------------------------------//
|
|
||||||
|
|
||||||
// (C) Copyright Boost.org 1999-2003. Permission to copy, use, modify, sell
|
|
||||||
// and distribute this software is granted provided this copyright
|
|
||||||
// notice appears in all copies. This software is provided "as is" without
|
|
||||||
// express or implied warranty, and with no claim as to its suitability for
|
|
||||||
// any purpose.
|
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility for documentation.
|
|
||||||
|
|
||||||
#ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED
|
|
||||||
#define BOOST_NEXT_PRIOR_HPP_INCLUDED
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Contributed by Dave Abrahams
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T next(T x) { return ++x; }
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T prior(T x) { return --x; }
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_NEXT_PRIOR_HPP_INCLUDED
|
|
@@ -1,33 +0,0 @@
|
|||||||
// Boost noncopyable.hpp header file --------------------------------------//
|
|
||||||
|
|
||||||
// (C) Copyright Boost.org 1999-2003. Permission to copy, use, modify, sell
|
|
||||||
// and distribute this software is granted provided this copyright
|
|
||||||
// notice appears in all copies. This software is provided "as is" without
|
|
||||||
// express or implied warranty, and with no claim as to its suitability for
|
|
||||||
// any purpose.
|
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility for documentation.
|
|
||||||
|
|
||||||
#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED
|
|
||||||
#define BOOST_NONCOPYABLE_HPP_INCLUDED
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// Private copy constructor and copy assignment ensure classes derived from
|
|
||||||
// class noncopyable cannot be copied.
|
|
||||||
|
|
||||||
// Contributed by Dave Abrahams
|
|
||||||
|
|
||||||
class noncopyable
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
noncopyable() {}
|
|
||||||
~noncopyable() {}
|
|
||||||
private: // emphasize the following members are private
|
|
||||||
noncopyable( const noncopyable& );
|
|
||||||
const noncopyable& operator=( const noncopyable& );
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_NONCOPYABLE_HPP_INCLUDED
|
|
@@ -6,12 +6,9 @@
|
|||||||
// software is provided "as is" without express or implied warranty, and
|
// software is provided "as is" without express or implied warranty, and
|
||||||
// with no claim as to its suitability for any purpose.
|
// with no claim as to its suitability for any purpose.
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// Revision History
|
||||||
// 21 Oct 02 Modified implementation of operators to allow compilers with a
|
|
||||||
// correct named return value optimization (NRVO) to produce optimal
|
|
||||||
// code. (Daniel Frey)
|
|
||||||
// 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
|
// 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
|
||||||
// 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
|
// 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
|
||||||
// 27 Aug 01 'left' form for non commutative operators added;
|
// 27 Aug 01 'left' form for non commutative operators added;
|
||||||
@@ -152,107 +149,127 @@ struct equality_comparable1 : B
|
|||||||
friend bool operator!=(const T& x, const T& y) { return !(x == y); }
|
friend bool operator!=(const T& x, const T& y) { return !(x == y); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct multipliable2 : B
|
||||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
{
|
||||||
|
friend T operator*(T x, const U& y) { return x *= y; }
|
||||||
// This is the optimal implementation for ISO/ANSI C++,
|
friend T operator*(const U& y, T x) { return x *= y; }
|
||||||
// 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; } \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
struct multipliable1 : B
|
||||||
struct NAME##2 : B \
|
{
|
||||||
{ \
|
friend T operator*(T x, const T& y) { return x *= y; }
|
||||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
|
||||||
struct NAME##2_left : 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; } \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct addable2 : B
|
||||||
// For compilers without NRVO the following code is optimal, but not symmetric!
|
{
|
||||||
// Note that the implementation of NAME##2_left only looks cool, but doesn't
|
friend T operator+(T x, const U& y) { return x += y; }
|
||||||
// provide optimization opportunities to the compiler :)
|
friend T operator+(const U& y, T x) { return x += y; }
|
||||||
|
|
||||||
#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; } \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
struct addable1 : B
|
||||||
struct NAME##2 : B \
|
{
|
||||||
{ \
|
friend T operator+(T x, const T& y) { return x += y; }
|
||||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
|
||||||
struct NAME##2_left : 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; } \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
|
struct subtractable2_left : B
|
||||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
|
{
|
||||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
|
friend T operator-(const U& x, const T& y)
|
||||||
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
|
{ T result(x); return result -= y; }
|
||||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
|
};
|
||||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
|
|
||||||
BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
|
|
||||||
|
|
||||||
#undef BOOST_BINARY_OPERATOR_COMMUTATIVE
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
|
struct subtractable1 : B
|
||||||
|
{
|
||||||
|
friend T operator-(T x, const T& y) { return x -= y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
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 U, class B = ::boost::detail::empty_base>
|
||||||
|
struct dividable2_left : B
|
||||||
|
{
|
||||||
|
friend T operator/(const U& x, const T& y)
|
||||||
|
{ T result(x); return result /= 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 U, class B = ::boost::detail::empty_base>
|
||||||
|
struct modable2_left : B
|
||||||
|
{
|
||||||
|
friend T operator%(const U& x, const T& y)
|
||||||
|
{ T result(x); return result %= y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct modable1 : B
|
||||||
|
{
|
||||||
|
friend T operator%(T x, const T& y) { return x %= y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct xorable2 : B
|
||||||
|
{
|
||||||
|
friend T operator^(T x, const U& y) { return x ^= y; }
|
||||||
|
friend T operator^(const U& y, T x) { return x ^= y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct xorable1 : B
|
||||||
|
{
|
||||||
|
friend T operator^(T x, const T& y) { return x ^= y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct andable2 : B
|
||||||
|
{
|
||||||
|
friend T operator&(T x, const U& y) { return x &= y; }
|
||||||
|
friend T operator&(const U& y, T x) { return x &= y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct andable1 : B
|
||||||
|
{
|
||||||
|
friend T operator&(T x, const T& y) { return x &= y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct orable2 : B
|
||||||
|
{
|
||||||
|
friend T operator|(T x, const U& y) { return x |= y; }
|
||||||
|
friend T operator|(const U& y, T x) { return x |= y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct orable1 : B
|
||||||
|
{
|
||||||
|
friend T operator|(T x, const T& y) { return x |= y; }
|
||||||
|
};
|
||||||
|
|
||||||
// incrementable and decrementable contributed by Jeremy Siek
|
// incrementable and decrementable contributed by Jeremy Siek
|
||||||
|
|
||||||
@@ -261,9 +278,9 @@ struct incrementable : B
|
|||||||
{
|
{
|
||||||
friend T operator++(T& x, int)
|
friend T operator++(T& x, int)
|
||||||
{
|
{
|
||||||
incrementable_type nrv(x);
|
incrementable_type tmp(x);
|
||||||
++x;
|
++x;
|
||||||
return nrv;
|
return tmp;
|
||||||
}
|
}
|
||||||
private: // The use of this typedef works around a Borland bug
|
private: // The use of this typedef works around a Borland bug
|
||||||
typedef T incrementable_type;
|
typedef T incrementable_type;
|
||||||
@@ -274,9 +291,9 @@ struct decrementable : B
|
|||||||
{
|
{
|
||||||
friend T operator--(T& x, int)
|
friend T operator--(T& x, int)
|
||||||
{
|
{
|
||||||
decrementable_type nrv(x);
|
decrementable_type tmp(x);
|
||||||
--x;
|
--x;
|
||||||
return nrv;
|
return tmp;
|
||||||
}
|
}
|
||||||
private: // The use of this typedef works around a Borland bug
|
private: // The use of this typedef works around a Borland bug
|
||||||
typedef T decrementable_type;
|
typedef T decrementable_type;
|
||||||
@@ -303,46 +320,30 @@ struct indexable : B
|
|||||||
};
|
};
|
||||||
|
|
||||||
// More operator classes (contributed by Daryle Walker) --------------------//
|
// More operator classes (contributed by Daryle Walker) --------------------//
|
||||||
// (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
|
|
||||||
|
|
||||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
|
struct left_shiftable2 : B
|
||||||
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
{
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
friend T operator<<(T x, const U& y) { return x <<= y; }
|
||||||
struct NAME##2 : B \
|
|
||||||
{ \
|
|
||||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template <class T, class B = ::boost::detail::empty_base> \
|
|
||||||
struct NAME##1 : B \
|
|
||||||
{ \
|
|
||||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
|
struct left_shiftable1 : B
|
||||||
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
{
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
friend T operator<<(T x, const T& y) { return x <<= y; }
|
||||||
struct NAME##2 : B \
|
|
||||||
{ \
|
|
||||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template <class T, class B = ::boost::detail::empty_base> \
|
|
||||||
struct NAME##1 : B \
|
|
||||||
{ \
|
|
||||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
BOOST_BINARY_OPERATOR( left_shiftable, << )
|
template <class T, class B = ::boost::detail::empty_base>
|
||||||
BOOST_BINARY_OPERATOR( right_shiftable, >> )
|
struct right_shiftable1 : B
|
||||||
|
{
|
||||||
#undef BOOST_BINARY_OPERATOR
|
friend T operator>>(T x, const T& y) { return x >>= y; }
|
||||||
|
};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||||
struct equivalent2 : B
|
struct equivalent2 : B
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
# include <boost/config.hpp>
|
# include <boost/config.hpp>
|
||||||
# include <boost/utility/addressof.hpp>
|
# include <boost/utility/addressof.hpp>
|
||||||
# include <boost/mpl/bool.hpp>
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ref.hpp - ref/cref, useful helper functions
|
// ref.hpp - ref/cref, useful helper functions
|
||||||
@@ -53,7 +52,7 @@ private:
|
|||||||
T* t_;
|
T* t_;
|
||||||
};
|
};
|
||||||
|
|
||||||
# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)
|
# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
|
||||||
# define BOOST_REF_CONST
|
# define BOOST_REF_CONST
|
||||||
# else
|
# else
|
||||||
# define BOOST_REF_CONST const
|
# define BOOST_REF_CONST const
|
||||||
@@ -74,14 +73,16 @@ template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const
|
|||||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class is_reference_wrapper
|
class is_reference_wrapper
|
||||||
: public mpl::false_
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class is_reference_wrapper<reference_wrapper<T> >
|
class is_reference_wrapper<reference_wrapper<T> >
|
||||||
: public mpl::true_
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -143,10 +144,8 @@ class is_reference_wrapper
|
|||||||
public:
|
public:
|
||||||
BOOST_STATIC_CONSTANT(
|
BOOST_STATIC_CONSTANT(
|
||||||
bool, value = (
|
bool, value = (
|
||||||
sizeof(detail::is_reference_wrapper_test(type<T>()))
|
sizeof(detail::is_reference_wrapper_test(type<T>()))
|
||||||
== sizeof(detail::yes_reference_wrapper_t)));
|
== sizeof(detail::yes_reference_wrapper_t)));
|
||||||
|
|
||||||
typedef ::boost::mpl::bool_<value> type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@@ -1,21 +1,63 @@
|
|||||||
// Boost utility.hpp header file -------------------------------------------//
|
// boost utility.hpp header file -------------------------------------------//
|
||||||
|
|
||||||
// (C) Copyright Boost.org 1999-2003. Permission to copy, use, modify, sell
|
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
|
||||||
// and distribute this software is granted provided this copyright
|
// and distribute this software is granted provided this copyright
|
||||||
// notice appears in all copies. This software is provided "as is" without
|
// 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
|
// express or implied warranty, and with no claim as to its suitability for
|
||||||
// any purpose.
|
// any purpose.
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility for documentation.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
|
// Classes appear in alphabetical order
|
||||||
|
|
||||||
#ifndef BOOST_UTILITY_HPP
|
#ifndef BOOST_UTILITY_HPP
|
||||||
#define BOOST_UTILITY_HPP
|
#define BOOST_UTILITY_HPP
|
||||||
|
|
||||||
#include <boost/utility/addressof.hpp>
|
// certain headers are part of the <utility.hpp> interface
|
||||||
#include <boost/utility/base_from_member.hpp>
|
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
#include <boost/next_prior.hpp>
|
#include <boost/utility/base_from_member.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/utility/addressof.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
// next() and prior() template functions -----------------------------------//
|
||||||
|
|
||||||
|
// Helper functions for classes like bidirectional iterators not supporting
|
||||||
|
// operator+ and operator-.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
// const std::list<T>::iterator p = get_some_iterator();
|
||||||
|
// const std::list<T>::iterator prev = boost::prior(p);
|
||||||
|
|
||||||
|
// Contributed by Dave Abrahams
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_UTILITY_HPP
|
#endif // BOOST_UTILITY_HPP
|
||||||
|
|
||||||
|
@@ -14,25 +14,13 @@
|
|||||||
// For more information, see http://www.boost.org
|
// For more information, see http://www.boost.org
|
||||||
|
|
||||||
#ifndef BOOST_UTILITY_ADDRESSOF_HPP
|
#ifndef BOOST_UTILITY_ADDRESSOF_HPP
|
||||||
# define BOOST_UTILITY_ADDRESSOF_HPP
|
#define BOOST_UTILITY_ADDRESSOF_HPP
|
||||||
|
|
||||||
# include <boost/config.hpp>
|
|
||||||
# include <boost/detail/workaround.hpp>
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
|
||||||
# include <boost/type_traits/add_pointer.hpp>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov)
|
// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov)
|
||||||
|
|
||||||
// VC7 strips const from nested classes unless we add indirection here
|
template <typename T> T* addressof(T& v)
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
|
||||||
template <typename T> typename add_pointer<T>::type
|
|
||||||
# else
|
|
||||||
template <typename T> T*
|
|
||||||
# endif
|
|
||||||
addressof(T& v)
|
|
||||||
{
|
{
|
||||||
return reinterpret_cast<T*>(
|
return reinterpret_cast<T*>(
|
||||||
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
|
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
|
||||||
|
@@ -1,82 +0,0 @@
|
|||||||
// (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
|
|
||||||
|
|
@@ -6,7 +6,7 @@
|
|||||||
// express or implied warranty, and with no claim as to its suitability for
|
// express or implied warranty, and with no claim as to its suitability for
|
||||||
// any purpose.
|
// any purpose.
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility for documentation.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
#ifndef BOOST_UTILITY_FWD_HPP
|
#ifndef BOOST_UTILITY_FWD_HPP
|
||||||
#define BOOST_UTILITY_FWD_HPP
|
#define BOOST_UTILITY_FWD_HPP
|
||||||
|
66
index.html
66
index.html
@@ -1,34 +1,34 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Language" content="en-us">
|
<head>
|
||||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
<meta http-equiv="Content-Language" content="en-us">
|
||||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||||
<title>Boost Utility Library</title>
|
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||||
</head>
|
<title>Boost Utility Library</title>
|
||||||
<body bgcolor="#FFFFFF">
|
</head>
|
||||||
<h1><IMG SRC="../../c++boost.gif" WIDTH="276" HEIGHT="86" align="center">Boost
|
|
||||||
Utility Library</h1>
|
<body bgcolor="#FFFFFF">
|
||||||
<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>
|
<h1><IMG SRC="../../c++boost.gif" WIDTH="276" HEIGHT="86" align="center">Boost
|
||||||
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
Utility Library</h1>
|
||||||
<blockquote>
|
<p>The Boost Utility Library isn't really a single library at all. It is
|
||||||
<p>
|
just a collection for components too small to be called libraries in their own
|
||||||
<a href="assert.html">assert</a><br>
|
right.</p>
|
||||||
<a href="base_from_member.html">base_from_member</a><br>
|
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
||||||
<a href="call_traits.htm">call_traits</a><br>
|
<blockquote>
|
||||||
<a href="checked_delete.html">checked_delete</a><br>
|
<p><a href="base_from_member.html">base_from_member</a><br>
|
||||||
<a href="compressed_pair.htm">compressed_pair</a><br>
|
<a href="call_traits.htm">call_traits.htm</a><br>
|
||||||
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
<a href="compressed_pair.htm">compressed_pair.htm</a><br>
|
||||||
<a href="operators.htm">operators</a><br>
|
<a href="operators.htm">operators.htm</a><br>
|
||||||
<a href="tie.html">tie</a><br>
|
<a href="tie.html">tie</a><br>
|
||||||
<a href="throw_exception.html">throw_exception</a><br>
|
<a href="utility.htm">utility.htm</a></p>
|
||||||
<a href="utility.htm">utility</a><br>
|
</blockquote>
|
||||||
<a href="value_init.htm">value_init</a></p>
|
<hr>
|
||||||
</blockquote>
|
<p>Revised
|
||||||
<hr>
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 May, 2002<!--webbot bot="Timestamp" endspan i-checksum="13976" --></p>
|
||||||
<p>Revised
|
<p> </p>
|
||||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->09 January, 2003<!--webbot bot="Timestamp" endspan i-checksum="38582" --></p>
|
|
||||||
<p> </p>
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
151
indirect_iterator_test.cpp
Normal file
151
indirect_iterator_test.cpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
// (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) || BOOST_MSVC > 1200 || !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_STD_ITERATOR_TRAITS
|
||||||
|
, 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_STD_ITERATOR_TRAITS
|
||||||
|
, 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_STD_ITERATOR_TRAITS
|
||||||
|
, 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_STD_ITERATOR_TRAITS
|
||||||
|
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_STD_ITERATOR_TRAITS
|
||||||
|
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;
|
||||||
|
}
|
27
iter_adaptor_fail_expected1.cpp
Normal file
27
iter_adaptor_fail_expected1.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
28
iter_adaptor_fail_expected2.cpp
Normal file
28
iter_adaptor_fail_expected2.cpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
61
iter_traits_gen_test.cpp
Normal file
61
iter_traits_gen_test.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// (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.
|
||||||
|
|
||||||
|
// 04 Nov 2001 Jeremy Siek
|
||||||
|
// Updated with respect to new named parameter interface.
|
||||||
|
// 08 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::reference_is<dummyT>,
|
||||||
|
boost::iterator_category_is<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::value_type_is<dummyT>,
|
||||||
|
boost::reference_is<const dummyT&>,
|
||||||
|
boost::pointer_is<const dummyT*> ,
|
||||||
|
boost::iterator_category_is<std::forward_iterator_tag>,
|
||||||
|
boost::difference_type_is<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;
|
||||||
|
}
|
449
iterator_adaptor_test.cpp
Normal file
449
iterator_adaptor_test.cpp
Normal file
@@ -0,0 +1,449 @@
|
|||||||
|
// 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
|
||||||
|
// 30 Nov 01 Added permutation_iterator.(Toon Knapen)
|
||||||
|
// 19 Nov 01 Added generator_iterator. (Jens Maurer)
|
||||||
|
// 04 Nov 01 Updated with respect to change in named parameters.
|
||||||
|
// (Jeremy Siek)
|
||||||
|
// 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 <numeric>
|
||||||
|
|
||||||
|
#include <boost/iterator_adaptors.hpp>
|
||||||
|
#include <boost/generator_iterator.hpp>
|
||||||
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
#include <boost/pending/integer_range.hpp>
|
||||||
|
#include <boost/concept_archetype.hpp>
|
||||||
|
#include <boost/type_traits/same_traits.hpp>
|
||||||
|
#include <boost/permutation_iterator.hpp>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
#include <set>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
template <class T> struct foo;
|
||||||
|
|
||||||
|
void blah(int) { }
|
||||||
|
|
||||||
|
struct my_gen
|
||||||
|
{
|
||||||
|
typedef int result_type;
|
||||||
|
my_gen() : n(0) { }
|
||||||
|
int operator()() { return ++n; }
|
||||||
|
int n;
|
||||||
|
};
|
||||||
|
|
||||||
|
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,
|
||||||
|
boost::iterator_adaptor<storage::iterator, boost::default_iterator_policies>,
|
||||||
|
boost::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t,
|
||||||
|
int*, int&>
|
||||||
|
> >();
|
||||||
|
|
||||||
|
// Test the named parameters
|
||||||
|
{
|
||||||
|
// Test computation of defaults
|
||||||
|
typedef boost::iterator_adaptor<int*, boost::default_iterator_policies,
|
||||||
|
boost::value_type_is<int> > Iter1;
|
||||||
|
// don't use std::iterator_traits here to avoid VC++ problems
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::value_type, int>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, int&>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, int*>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::difference_type, std::ptrdiff_t>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::iterator_category, std::random_access_iterator_tag>::value));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Test computation of default when the Value is const
|
||||||
|
typedef boost::iterator_adaptor<std::list<int>::iterator,
|
||||||
|
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) && 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));
|
||||||
|
#else
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, const int&>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, const int*>::value));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Test with no defaults
|
||||||
|
typedef boost::iterator_adaptor<int*, boost::default_iterator_policies,
|
||||||
|
boost::reference_is<long>,
|
||||||
|
boost::pointer_is<float*>,
|
||||||
|
boost::value_type_is<char>,
|
||||||
|
boost::iterator_category_is<std::input_iterator_tag>,
|
||||||
|
boost::difference_type_is<int>
|
||||||
|
> Iter1;
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::value_type, char>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, long>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, float*>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::difference_type, int>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<Iter1::iterator_category, std::input_iterator_tag>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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*
|
||||||
|
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
|
||||||
|
, dummyT
|
||||||
|
#endif
|
||||||
|
>::type reverse_iterator;
|
||||||
|
|
||||||
|
reverse_iterator i(reversed + N);
|
||||||
|
boost::random_access_iterator_test(i, N, array);
|
||||||
|
|
||||||
|
#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*
|
||||||
|
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
|
||||||
|
, dummyT, const dummyT&, 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;
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
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_MSVC > 1200)
|
||||||
|
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*
|
||||||
|
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
|
||||||
|
, 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) || 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(
|
||||||
|
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) || 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()),
|
||||||
|
boost::make_reverse_iterator(array2.begin())
|
||||||
|
),
|
||||||
|
dummyT(4), dummyT(1));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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));
|
||||||
|
|
||||||
|
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::reference_is<const dummyT&>,
|
||||||
|
boost::pointer_is<const dummyT*> ,
|
||||||
|
boost::iterator_category_is<std::forward_iterator_tag>,
|
||||||
|
boost::value_type_is<dummyT>,
|
||||||
|
boost::difference_type_is<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());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// check generator_iterator
|
||||||
|
my_gen g1;
|
||||||
|
boost::generator_iterator_generator<my_gen>::type gen =
|
||||||
|
boost::make_generator_iterator(g1);
|
||||||
|
assert(*gen == 1);
|
||||||
|
++gen;
|
||||||
|
gen++;
|
||||||
|
assert(*gen == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// check permutation_iterator
|
||||||
|
typedef std::deque< int > element_range_type;
|
||||||
|
typedef std::list< int > index_type;
|
||||||
|
|
||||||
|
static const int element_range_size = 10;
|
||||||
|
static const int index_size = 4;
|
||||||
|
|
||||||
|
element_range_type elements( element_range_size );
|
||||||
|
|
||||||
|
for(element_range_type::iterator el_it = elements.begin();
|
||||||
|
el_it != elements.end();
|
||||||
|
++el_it)
|
||||||
|
{
|
||||||
|
*el_it = std::distance( elements.begin(), el_it );
|
||||||
|
}
|
||||||
|
|
||||||
|
index_type indices( index_size );
|
||||||
|
|
||||||
|
for(index_type::iterator i_it = indices.begin();
|
||||||
|
i_it != indices.end();
|
||||||
|
++i_it)
|
||||||
|
{
|
||||||
|
*i_it = element_range_size - index_size
|
||||||
|
+ std::distance(indices.begin(), i_it );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::reverse( indices.begin(), indices.end() );
|
||||||
|
|
||||||
|
typedef boost::permutation_iterator_generator< element_range_type::iterator, index_type::iterator >::type permutation_type;
|
||||||
|
permutation_type begin = boost::make_permutation_iterator( elements.begin(), indices.begin() );
|
||||||
|
permutation_type end = boost::make_permutation_iterator( elements.begin(), indices.end() );
|
||||||
|
|
||||||
|
int expected_outcome[] = { 9, 8, 7, 6 };
|
||||||
|
assert( std::equal( begin, end, expected_outcome ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "test successful " << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -128,8 +128,6 @@
|
|||||||
<a href="generator_iterator.htm">Generator Iterator Adaptor</a>
|
<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>
|
<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>
|
<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>
|
</ul>
|
||||||
|
|
||||||
<p><b><a href="../../people/dave_abrahams.htm">Dave
|
<p><b><a href="../../people/dave_abrahams.htm">Dave
|
||||||
@@ -158,9 +156,6 @@
|
|||||||
adaptor.<br>
|
adaptor.<br>
|
||||||
Toon Knapen contributed the <a href="permutation_iterator.htm">permutation
|
Toon Knapen contributed the <a href="permutation_iterator.htm">permutation
|
||||||
iterator</a> adaptor.<br>
|
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>
|
<h2><a name="iterator_adaptor">Class template</a>
|
||||||
<tt>iterator_adaptor</tt></h2>
|
<tt>iterator_adaptor</tt></h2>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// (C) Copyright David Abrahams 2002. Permission to copy, use, modify,
|
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||||
// sell and distribute this software is granted provided this
|
// sell and distribute this software is granted provided this
|
||||||
// copyright notice appears in all copies. This software is provided
|
// copyright notice appears in all copies. This software is provided
|
||||||
// "as is" without express or implied warranty, and with no claim as
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
// 19 Jan 2001 Initial version with iterator operators (David Abrahams)
|
// 19 Jan 2001 Initial version with iterator operators (David Abrahams)
|
||||||
|
|
||||||
#include <boost/detail/iterator.hpp>
|
#include <boost/detail/iterator.hpp>
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits.hpp>
|
||||||
#include <boost/operators.hpp>
|
#include <boost/operators.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
@@ -31,11 +31,6 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// A UDT for which we can specialize std::iterator_traits<element*> on
|
|
||||||
// compilers which don't support partial specialization. There's no
|
|
||||||
// other reasonable way to test pointers on those compilers.
|
|
||||||
struct element {};
|
|
||||||
|
|
||||||
// An iterator for which we can get traits.
|
// An iterator for which we can get traits.
|
||||||
struct my_iterator1
|
struct my_iterator1
|
||||||
: boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&>
|
: boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&>
|
||||||
@@ -82,37 +77,27 @@ struct my_iterator2
|
|||||||
struct my_iterator3 : my_iterator1
|
struct my_iterator3 : my_iterator1
|
||||||
{
|
{
|
||||||
typedef int difference_type;
|
typedef int difference_type;
|
||||||
my_iterator3(const char* p)
|
my_iterator3(const char* p) : my_iterator1(p) {}
|
||||||
: my_iterator1(p) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
// Assertion tools. Used instead of BOOST_STATIC_ASSERT because that
|
|
||||||
// doesn't give us a nice stack backtrace
|
|
||||||
//
|
|
||||||
template <bool = false> struct assertion;
|
|
||||||
|
|
||||||
template <> struct assertion<true>
|
|
||||||
{
|
|
||||||
typedef char type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class U>
|
|
||||||
struct assert_same
|
|
||||||
: assertion<(::boost::is_same<T,U>::value)>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Iterator tests
|
|
||||||
template <class Iterator,
|
template <class Iterator,
|
||||||
class value_type, class difference_type, class pointer, class reference, class category>
|
class value_type, class difference_type, class pointer, class reference, class category>
|
||||||
struct non_portable_tests
|
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>::pointer test_pt;
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::reference test_rt;
|
typedef typename boost::detail::iterator_traits<Iterator>::reference test_rt;
|
||||||
typedef typename assert_same<test_pt, pointer>::type a1;
|
BOOST_STATIC_ASSERT((
|
||||||
typedef typename assert_same<test_rt, reference>::type a2;
|
::boost::is_same<
|
||||||
|
test_pt,
|
||||||
|
pointer
|
||||||
|
>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
::boost::is_same<
|
||||||
|
test_rt,
|
||||||
|
reference
|
||||||
|
>::value));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Iterator,
|
template <class Iterator,
|
||||||
@@ -121,8 +106,17 @@ struct portable_tests
|
|||||||
{
|
{
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type test_dt;
|
typedef typename boost::detail::iterator_traits<Iterator>::difference_type test_dt;
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category test_cat;
|
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category test_cat;
|
||||||
typedef typename assert_same<test_dt, difference_type>::type a1;
|
BOOST_STATIC_ASSERT((
|
||||||
typedef typename assert_same<test_cat, category>::type a2;
|
::boost::is_same<
|
||||||
|
test_dt,
|
||||||
|
difference_type
|
||||||
|
>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
::boost::is_same<
|
||||||
|
test_cat,
|
||||||
|
category
|
||||||
|
>::value));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test iterator_traits
|
// Test iterator_traits
|
||||||
@@ -132,7 +126,11 @@ struct input_iterator_test
|
|||||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||||
{
|
{
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type test_vt;
|
typedef typename boost::detail::iterator_traits<Iterator>::value_type test_vt;
|
||||||
typedef typename assert_same<test_vt, value_type>::type a1;
|
BOOST_STATIC_ASSERT((
|
||||||
|
::boost::is_same<
|
||||||
|
test_vt,
|
||||||
|
value_type
|
||||||
|
>::value));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Iterator,
|
template <class Iterator,
|
||||||
@@ -156,13 +154,14 @@ struct maybe_pointer_test
|
|||||||
input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag>
|
input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag>
|
||||||
istream_iterator_test;
|
istream_iterator_test;
|
||||||
|
|
||||||
|
//
|
||||||
#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT)
|
#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT)
|
||||||
typedef ::std::char_traits<char>::off_type distance;
|
typedef ::std::char_traits<char>::off_type distance;
|
||||||
non_pointer_test<std::ostream_iterator<int>,int,
|
non_pointer_test<std::ostream_iterator<int>,int,
|
||||||
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
|
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
|
||||||
#elif defined(BOOST_MSVC_STD_ITERATOR)
|
#elif defined(BOOST_MSVC_STD_ITERATOR)
|
||||||
non_pointer_test<std::ostream_iterator<int>,
|
non_pointer_test<std::ostream_iterator<int>,
|
||||||
int, void, int*, int&, std::output_iterator_tag>
|
int, void, void, void, std::output_iterator_tag>
|
||||||
ostream_iterator_test;
|
ostream_iterator_test;
|
||||||
#else
|
#else
|
||||||
non_pointer_test<std::ostream_iterator<int>,
|
non_pointer_test<std::ostream_iterator<int>,
|
||||||
@@ -176,7 +175,6 @@ non_pointer_test<std::ostream_iterator<int>,
|
|||||||
#else
|
#else
|
||||||
typedef std::ptrdiff_t std_list_diff_type;
|
typedef std::ptrdiff_t std_list_diff_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag>
|
non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag>
|
||||||
list_iterator_test;
|
list_iterator_test;
|
||||||
|
|
||||||
@@ -191,16 +189,16 @@ non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forwar
|
|||||||
|
|
||||||
non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag>
|
non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||||
my_iterator2_test;
|
my_iterator2_test;
|
||||||
|
|
||||||
non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag>
|
non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag>
|
||||||
my_iterator3_test;
|
my_iterator3_test;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
char chars[100];
|
char chars[100];
|
||||||
int ints[100];
|
int ints[100];
|
||||||
|
|
||||||
for (int length = 3; length < 100; length += length / 3)
|
for (std::ptrdiff_t length = 3; length < 100; length += length / 3)
|
||||||
{
|
{
|
||||||
std::list<int> l(length);
|
std::list<int> l(length);
|
||||||
assert(boost::detail::distance(l.begin(), l.end()) == length);
|
assert(boost::detail::distance(l.begin(), l.end()) == length);
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
// 9 Jun 99 Add unnamed namespace
|
// 9 Jun 99 Add unnamed namespace
|
||||||
// 2 Jun 99 Initial Version
|
// 2 Jun 99 Initial Version
|
||||||
|
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// This program demonstrates compiler errors resulting from trying to copy
|
// This program demonstrates compiler errors resulting from trying to copy
|
||||||
|
3127
operators.htm
3127
operators.htm
File diff suppressed because it is too large
Load Diff
@@ -569,7 +569,7 @@ test_main( int , char * [] )
|
|||||||
|
|
||||||
cout << "Created point, and operated on it." << endl;
|
cout << "Created point, and operated on it." << endl;
|
||||||
|
|
||||||
for (int n = 0; n < 1000; ++n) // was 10,000 but took too long (Beman)
|
for (int n = 0; n < 10000; ++n)
|
||||||
{
|
{
|
||||||
boost::minstd_rand r;
|
boost::minstd_rand r;
|
||||||
tester<long, int>()(r);
|
tester<long, int>()(r);
|
||||||
|
@@ -1,332 +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>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 <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>>
|
|
||||||
class shared_container_iterator_generator;
|
|
||||||
|
|
||||||
template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>>
|
|
||||||
typename shared_container_iterator_generator<Container>::type
|
|
||||||
make_shared_container_iterator(typename Container::iterator base,
|
|
||||||
boost::shared_ptr<Container> const& container);
|
|
||||||
|
|
||||||
std::pair<
|
|
||||||
typename shared_container_iterator_generator<Container>::type,
|
|
||||||
typename shared_container_iterator_generator<Container>::type
|
|
||||||
>
|
|
||||||
make_shared_container_range(boost::shared_ptr<Container> const& 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 <typename Container>
|
|
||||||
class shared_container_iterator_generator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> 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 <algorithm></font>
|
|
||||||
<font color="#008040">#include <iostream></font>
|
|
||||||
<font color="#008040">#include <vector></font>
|
|
||||||
|
|
||||||
<B>typedef</B> boost::shared_container_iterator_generator< std::vector<<B>int</B>> >::type 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 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& 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>
|
|
||||||
typename shared_container_iterator_generator<AdaptableUnaryFunction,BaseIterator>::type
|
|
||||||
make_shared_container_iterator(Container::iterator base,
|
|
||||||
boost::shared_ptr<Container> const& 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 <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<
|
|
||||||
typename shared_container_iterator_generator<Container>::type,
|
|
||||||
typename shared_container_iterator_generator<Container>::type
|
|
||||||
>
|
|
||||||
make_shared_container_range(boost::shared_ptr<Container> const& 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->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>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 <algorithm> // for std::copy</font>
|
|
||||||
<font color="#008040">#include <iostream> </font>
|
|
||||||
<font color="#008040">#include <vector></font>
|
|
||||||
|
|
||||||
|
|
||||||
<B>typedef</B> boost::shared_container_iterator_generator< std::vector<<B>int</B>> >::type
|
|
||||||
function_iterator;
|
|
||||||
|
|
||||||
std::pair<function_iterator,function_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() {
|
|
||||||
|
|
||||||
|
|
||||||
function_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: 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 "as is"
|
|
||||||
without express or implied warranty, and with no claim as to its suitability for
|
|
||||||
any purpose.</p>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@@ -1,42 +0,0 @@
|
|||||||
// (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;
|
|
||||||
}
|
|
@@ -1,42 +0,0 @@
|
|||||||
// (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;
|
|
||||||
}
|
|
@@ -1,41 +0,0 @@
|
|||||||
// (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;
|
|
||||||
}
|
|
@@ -1,60 +0,0 @@
|
|||||||
<!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="../../c++boost.gif" alt="c++boost.gif (8819 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>
|
|
@@ -19,7 +19,7 @@ Defined in header
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
The transform iterator adaptor augments an iterator by applying some
|
The transform iterator adaptor augments an iterator by applying some
|
||||||
function object to the result of dereferencing the iterator. In other
|
function object to the result of dereferencing the iterator. Another
|
||||||
words, the <tt>operator*</tt> of the transform iterator first
|
words, the <tt>operator*</tt> of the transform iterator first
|
||||||
dereferences the base iterator, passes the result of this to the
|
dereferences the base iterator, passes the result of this to the
|
||||||
function object, and then returns the result. The following
|
function object, and then returns the result. The following
|
||||||
|
54
transform_iterator_test.cpp
Normal file
54
transform_iterator_test.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// (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 transform 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>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
const int N = 10;
|
||||||
|
|
||||||
|
// Borland is getting confused about typedef's and constructors here
|
||||||
|
|
||||||
|
// Test transform_iterator
|
||||||
|
{
|
||||||
|
int x[N], y[N];
|
||||||
|
for (int k = 0; k < N; ++k)
|
||||||
|
x[k] = k;
|
||||||
|
std::copy(x, x + N, y);
|
||||||
|
|
||||||
|
for (int k2 = 0; k2 < N; ++k2)
|
||||||
|
x[k2] = x[k2] * 2;
|
||||||
|
|
||||||
|
boost::transform_iterator_generator<mult_functor, int*>::type i(y, mult_functor(2));
|
||||||
|
boost::input_iterator_test(i, x[0], x[1]);
|
||||||
|
boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_functor(2)), x[0], x[1]);
|
||||||
|
}
|
||||||
|
std::cout << "test successful " << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
278
utility.htm
278
utility.htm
@@ -1,113 +1,168 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
<head>
|
||||||
<title>Header boost/utility.hpp Documentation</title>
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
</head>
|
<title>Header boost/utility.hpp Documentation</title>
|
||||||
<body bgcolor="#FFFFFF" text="#000000">
|
</head>
|
||||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
|
|
||||||
<a href="../../boost/utility.hpp">boost/utility.hpp</a></h1>
|
<body bgcolor="#FFFFFF" text="#000000">
|
||||||
<p>The entire contents of the header <code><a href="../../boost/utility.hpp"><boost/utility.hpp></a></code>
|
|
||||||
are in <code>namespace boost</code>.</p>
|
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
|
||||||
<h2>Contents</h2>
|
<a href="../../boost/utility.hpp">boost/utility.hpp</a></h1>
|
||||||
<ul>
|
|
||||||
<li>
|
<p>The entire contents of the header <code><a href="../../boost/utility.hpp"><boost/utility.hpp></a></code>
|
||||||
Class templates supporting the <a href="base_from_member.html">base-from-member
|
are in <code>namespace boost</code>.</p>
|
||||||
idiom</a></li>
|
|
||||||
<li>
|
<h2>Contents</h2>
|
||||||
Function templates <a href="#checked_delete">checked_delete() and
|
|
||||||
checked_array_delete()</a></li>
|
<ul>
|
||||||
<li>
|
<li>Class templates supporting the <a href="base_from_member.html">base-from-member
|
||||||
Function templates <a href="#functions_next_prior">next() and prior()</a></li>
|
idiom</a></li>
|
||||||
<li>
|
<li>Function templates <a href="#checked_delete">checked_delete() and
|
||||||
Class <a href="#Class_noncopyable">noncopyable</a></li>
|
checked_array_delete()</a></li>
|
||||||
<li>
|
<li>Function templates <a href="#functions next">next() and prior()</a></li>
|
||||||
Function template <a href="#addressof">addressof()</a></li>
|
<li>Class <a href="#Class noncopyable">noncopyable</a></li>
|
||||||
<li>
|
<li>Function template <a href="#addressof">addressof()</a></li>
|
||||||
Function template <a href="tie.html">tie()</a> and supporting class tied.</li>
|
<li>Function template <a href="tie.html">tie()</a> and supporting class tied.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2>
|
<h2> Function templates <a name="checked_delete">checked_delete</a>() and
|
||||||
Function templates <a name="checked_delete">checked_delete</a>() and
|
checked_array_delete()</h2>
|
||||||
checked_array_delete()</h2>
|
|
||||||
<p>See <a href="checked_delete.html">separate documentation</a>.</p>
|
<p>Deletion of a pointer to an incomplete type is an unsafe programming practice
|
||||||
<h2>
|
because there is no way for the compiler to verify that the destructor is indeed
|
||||||
<a name="functions_next_prior">Function</a> templates next() and prior()</h2>
|
trivial. The checked_delete() and checked_array_delete() function
|
||||||
<p>Certain data types, such as the C++ Standard Library's forward and bidirectional
|
templates simply <b>delete</b> or <b>delete[]</b> their argument, but also
|
||||||
iterators, do not provide addition and subtraction via operator+() or
|
require that their argument be a complete type. They issue an appropriate
|
||||||
operator-(). This means that non-modifying computation of the next or
|
compiler error diagnostic if that requirement is not met. A typical
|
||||||
prior value requires a temporary, even though operator++() or operator--() is
|
implementation is shown; other implementations may vary:</p>
|
||||||
provided. It also means that writing code like <code>itr+1</code> inside
|
|
||||||
a template restricts the iterator category to random access iterators.</p>
|
<pre> template< typename T >
|
||||||
<p>The next() and prior() functions provide a simple way around these problems:</p>
|
inline void checked_delete(T const volatile * x)
|
||||||
<blockquote>
|
{
|
||||||
<pre>template <class T>
|
BOOST_STATIC_ASSERT( sizeof(T) ); // assert type complete at point
|
||||||
|
// of instantiation
|
||||||
|
delete x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
inline void checked_array_delete(T const volatile * x)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT( sizeof(T) ); // assert type complete at point
|
||||||
|
// of instantiation
|
||||||
|
delete [] x;
|
||||||
|
}</pre>
|
||||||
|
|
||||||
|
<p>Contributed by Beman Dawes, based on a suggestion from Dave Abrahams,
|
||||||
|
generalizing an idea from Vladimir Prus, with comments from Rainer Deyke, John
|
||||||
|
Maddock, and others.</p>
|
||||||
|
|
||||||
|
<h3>Background</h3>
|
||||||
|
|
||||||
|
<p>The C++ Standard specifies that delete on a pointer to an incomplete types is
|
||||||
|
undefined behavior if the type has a non-trivial destructor in [expr.delete]
|
||||||
|
5.3.5 paragraph. No diagnostic is required. Some but not all
|
||||||
|
compilers issue warnings if the type is incomplete at point of deletion.</p>
|
||||||
|
|
||||||
|
<h2> <a name="functions next">Function</a> templates next() and prior()</h2>
|
||||||
|
|
||||||
|
<p>Certain data types, such as the C++ Standard Library's forward and
|
||||||
|
bidirectional iterators, do not provide addition and subtraction via operator+()
|
||||||
|
or operator-(). This means that non-modifying computation of the next or
|
||||||
|
prior value requires a temporary, even though operator++() or operator--() is
|
||||||
|
provided. It also means that writing code like <code>itr+1</code> inside a
|
||||||
|
template restricts the iterator category to random access iterators.</p>
|
||||||
|
|
||||||
|
<p>The next() and prior() functions provide a simple way around these problems:</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
|
||||||
|
<pre>template <class T>
|
||||||
T next(T x) { return ++x; }
|
T next(T x) { return ++x; }
|
||||||
|
|
||||||
template <class X>
|
template <class X>
|
||||||
T prior(T x) { return --x; }</pre>
|
T prior(T x) { return --x; }</pre>
|
||||||
</blockquote>
|
|
||||||
<p>Usage is simple:</p>
|
</blockquote>
|
||||||
<blockquote>
|
|
||||||
<pre>const std::list<T>::iterator p = get_some_iterator();
|
<p>Usage is simple:</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
|
||||||
|
<pre>const std::list<T>::iterator p = get_some_iterator();
|
||||||
const std::list<T>::iterator prev = boost::prior(p);</pre>
|
const std::list<T>::iterator prev = boost::prior(p);</pre>
|
||||||
</blockquote>
|
|
||||||
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
|
</blockquote>
|
||||||
<h2><a name="Class_noncopyable">Class noncopyable</a></h2>
|
|
||||||
<p>Class <strong>noncopyable</strong> is a base class. Derive your own class
|
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
|
||||||
from <strong>noncopyable</strong> when you want to prohibit copy construction
|
|
||||||
and copy assignment.</p>
|
<h2><a name="Class noncopyable">Class noncopyable</a></h2>
|
||||||
<p>Some objects, particularly those which hold complex resources like files or
|
|
||||||
network connections, have no sensible copy semantics. Sometimes there are
|
<p>Class <strong>noncopyable</strong> is a base class. Derive your own class from <strong>noncopyable</strong>
|
||||||
possible copy semantics, but these would be of very limited usefulness and be
|
when you want to prohibit copy construction and copy assignment.</p>
|
||||||
very difficult to implement correctly. Sometimes you're implementing a
|
|
||||||
class that doesn't need to be copied just yet and you don't want to take the
|
<p>Some objects, particularly those which hold complex resources like files or
|
||||||
time to write the appropriate functions. Deriving from <b>noncopyable</b>
|
network connections, have no sensible copy semantics. Sometimes there are
|
||||||
will prevent the otherwise implicitly-generated functions (which don't have the
|
possible copy semantics, but these would be of very limited usefulness and be
|
||||||
proper semantics) from becoming a trap for other programmers.</p>
|
very difficult to implement correctly. Sometimes you're implementing a class that doesn't need to be copied
|
||||||
<p>The traditional way to deal with these is to declare a private copy constructor
|
just yet and you don't want to take the time to write the appropriate functions.
|
||||||
and copy assignment, and then document why this is done. But deriving
|
Deriving from <b> noncopyable</b> will prevent the otherwise implicitly-generated
|
||||||
from <b>noncopyable</b> is simpler and clearer, and doesn't require additional
|
functions (which don't have the proper semantics) from becoming a trap for other programmers.</p>
|
||||||
documentation.</p>
|
|
||||||
<p>The program <a href="noncopyable_test.cpp">noncopyable_test.cpp</a> can be used
|
<p>The traditional way to deal with these is to declare a private copy constructor and copy assignment, and then
|
||||||
to verify class <b>noncopyable</b> works as expected. It has have been run
|
document why this is done. But deriving from <b>noncopyable</b> is simpler
|
||||||
successfully under GCC 2.95, Metrowerks CodeWarrior 5.0, and Microsoft Visual
|
and clearer, and doesn't require additional documentation.</p>
|
||||||
C++ 6.0 sp 3.</p>
|
|
||||||
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
|
<p>The program <a href="noncopyable_test.cpp">noncopyable_test.cpp</a> can be
|
||||||
<h3>Example</h3>
|
used to verify class <b>noncopyable</b> works as expected. It has have been run successfully under
|
||||||
<blockquote>
|
GCC 2.95, Metrowerks
|
||||||
<pre>// inside one of your own headers ...
|
CodeWarrior 5.0, and Microsoft Visual C++ 6.0 sp 3.</p>
|
||||||
|
|
||||||
|
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
|
||||||
|
|
||||||
|
<h3>Example</h3>
|
||||||
|
<blockquote>
|
||||||
|
<pre>// inside one of your own headers ...
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
class ResourceLadenFileSystem : boost::noncopyable {
|
class ResourceLadenFileSystem : boost::noncopyable {
|
||||||
...</pre>
|
...</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<h3>Rationale</h3>
|
|
||||||
<p>Class noncopyable has protected constructor and destructor members to emphasize
|
<h3>Rationale</h3>
|
||||||
that it is to be used only as a base class. Dave Abrahams notes concern
|
<p>Class noncopyable has protected constructor and destructor members to
|
||||||
about the effect on compiler optimization of adding (even trivial inline)
|
emphasize that it is to be used only as a base class. Dave Abrahams notes
|
||||||
destructor declarations. He says "Probably this concern is misplaced,
|
concern about the effect on compiler optimization of adding (even trivial inline)
|
||||||
because noncopyable will be used mostly for classes which own resources and
|
destructor declarations. He says "Probably this concern is misplaced, because
|
||||||
thus have non-trivial destruction semantics."</p>
|
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics."</p>
|
||||||
<h2><a name="addressof">Function template addressof()</a></h2>
|
<h2><a name="addressof">Function template addressof()</a></h2>
|
||||||
<p>Function <strong>addressof()</strong> returns the address of an object.</p>
|
<p>Function <strong>addressof()</strong> returns the address of an object.</p>
|
||||||
<blockquote>
|
|
||||||
<pre>template <typename T> inline T* addressof(T& v);
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
template <typename T> inline T* addressof(T& v);
|
||||||
template <typename T> inline const T* addressof(const T& v);
|
template <typename T> inline const T* addressof(const T& v);
|
||||||
template <typename T> inline volatile T* addressof(volatile T& v);
|
template <typename T> inline volatile T* addressof(volatile T& v);
|
||||||
template <typename T> inline const volatile T* addressof(const volatile T& v);
|
template <typename T> inline const volatile T* addressof(const volatile T& v);
|
||||||
</pre>
|
</pre>
|
||||||
</blockquote>
|
</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>.
|
<p>C++ allows programmers to replace the unary
|
||||||
Function <strong>addressof()</strong> provides a wrapper around the necessary
|
<strong>operator&()</strong> class member used to get the address of
|
||||||
code to make it easy to get an object's real address.
|
an object. Getting the real address of an object requires ugly
|
||||||
</p>
|
casting tricks to avoid invoking the overloaded
|
||||||
<p>The program <a href="addressof_test.cpp">addressof_test.cpp</a> can be used to
|
<strong>operator&()</strong>. Function <strong>addressof()</strong>
|
||||||
verify that <b>addressof()</b> works as expected.</p>
|
provides a wrapper around the necessary code to make it easy to get an
|
||||||
<p>Contributed by Brad King based on ideas from discussion with Doug Gregor.</p>
|
object's real address.
|
||||||
<h3>Example</h3>
|
</p>
|
||||||
<blockquote>
|
|
||||||
<pre>#include <boost/utility.hpp>
|
<p>The program <a href="addressof_test.cpp">addressof_test.cpp</a> can be
|
||||||
|
used to verify that <b>addressof()</b> works as expected.</p>
|
||||||
|
|
||||||
|
<p>Contributed by Brad King based on ideas from discussion with Doug Gregor.</p>
|
||||||
|
<h3>Example</h3>
|
||||||
|
<blockquote>
|
||||||
|
<pre>#include <boost/utility.hpp>
|
||||||
|
|
||||||
struct useless_type {};
|
struct useless_type {};
|
||||||
class nonaddressable {
|
class nonaddressable {
|
||||||
@@ -119,19 +174,20 @@ void f() {
|
|||||||
nonaddressable* xp = boost::addressof(x);
|
nonaddressable* xp = boost::addressof(x);
|
||||||
// nonaddressable* xpe = &x; /* error */
|
// nonaddressable* xpe = &x; /* error */
|
||||||
}</pre>
|
}</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<h2>Class templates for the Base-from-Member Idiom</h2>
|
|
||||||
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
<h2>Class templates for the Base-from-Member Idiom</h2>
|
||||||
<h2>Function template tie()</h2>
|
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
||||||
<p>See <a href="tie.html">separate documentation</a>.</p>
|
<h2>Function template tie()</h2>
|
||||||
<hr>
|
<p>See <a href="tie.html">separate documentation</a>.</p>
|
||||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
|
<hr>
|
||||||
-->09 January, 2003<!--webbot bot="Timestamp" endspan i-checksum="38582"
|
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
|
||||||
|
-->10 September, 2001<!--webbot bot="Timestamp" endspan i-checksum="39328"
|
||||||
-->
|
-->
|
||||||
</p>
|
</p>
|
||||||
<p><EFBFBD> Copyright boost.org 1999-2002. Permission to copy, use, modify, sell and distribute
|
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
|
||||||
this document is granted provided this copyright notice appears in all copies.
|
distribute this document is granted provided this copyright notice appears in
|
||||||
This document is provided "as is" without express or implied
|
all copies. This document is provided "as is" without express or
|
||||||
warranty, and with no claim as to its suitability for any purpose.</p>
|
implied warranty, and with no claim as to its suitability for any purpose.</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
219
value_init.htm
219
value_init.htm
@@ -1,219 +0,0 @@
|
|||||||
<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 <<a href="../../boost/utility/value_init.hpp">boost/utility/value_init.hpp</a>>
|
|
||||||
</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<></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 §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<class T> void eat(T);<br>int x ; // indeterminate initial value.<br>std::string s; // default-initialized.<br>eat ( int() ) ; // value-initialized<br>eat ( std::string() ) ; // value-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<class T> <br>struct W <br>{<br> // value-initialization of 'data' here.<br> W() : data() {}<br> T data ;<br>} ;<br>W<int> w ;<br>// w.data is value-initialized for any type. </pre>
|
|
||||||
|
|
||||||
<p><code>This is the solution supplied by the value_initialized<> template
|
|
||||||
class.</code></p>
|
|
||||||
|
|
||||||
<h2><a name="types"></a>Types</h2>
|
|
||||||
|
|
||||||
<h2><a name="val_init"><code>template class value_initialized<T></code></a></h2>
|
|
||||||
|
|
||||||
<pre>namespace boost {<br><br>template<class T><br>class value_initialized<br>{<br> public :<br> value_initialized() : x() {}<br> operator T&() const { return x ; }<br> T& data() const { return x ; }<br><br> private :<br> <i>impll-defined</i> x ;<br>} ;<br><br>template<class T><br>T const& get ( value_initialized<T> const& x )<br>{<br> return x.data() ;<br>}<br><br>template<class T><br>T& get ( value_initialized<T>& x )<br>{<br> return x.data() ;<br>}<br><br>} // namespace boost<br></pre>
|
|
||||||
|
|
||||||
<p>An object of this template class is a <code>T</code>-wrapper convertible
|
|
||||||
to <code>'T&'</code> whose wrapped object (data member of type <code>T</code>)
|
|
||||||
is <a href="#valueinit">value-initialized</a> upon default-initialization
|
|
||||||
of this wrapper class: </p>
|
|
||||||
|
|
||||||
<pre>int zero = 0 ;<br>value_initialized<int> x ;<br>assert ( x == zero ) ;<br><br>std::string def ;<br>value_initialized< std::string > y ;<br>assert ( y == def ) ;<br></pre>
|
|
||||||
|
|
||||||
<p>The purpose of this wrapper is to provide a consistent syntax for value
|
|
||||||
initialization of scalar, union and class types (POD and non-POD) since
|
|
||||||
the correct syntax for value initialization varies (see <a
|
|
||||||
href="#valueinitsyn">value-initialization syntax</a>)</p>
|
|
||||||
|
|
||||||
<p>The wrapped object can be accessed either through the conversion operator
|
|
||||||
<code>T&</code>, the member function <code>data()</code>, or the
|
|
||||||
non-member function <code>get()</code>: </p>
|
|
||||||
|
|
||||||
<pre>void watch(int);<br>value_initialized<int> x;<br><br>watch(x) ; // operator T& used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
|
|
||||||
|
|
||||||
<p>Both <code>const</code> and non-<code>const</code> objects can be wrapped.
|
|
||||||
Mutable objects can be modified directly from within the wrapper but constant
|
|
||||||
objects cannot:</p>
|
|
||||||
|
|
||||||
<pre>value_initialized<int> x ; <br>static_cast<int&>(x) = 1 ; // OK<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> y ; <br>static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int&<br>static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
|
|
||||||
|
|
||||||
<h3>Warning:</h3>
|
|
||||||
|
|
||||||
<p>Both the conversion operator and the <code>data()</code> member function
|
|
||||||
are <code>const</code> in order to allow access to the wrapped object
|
|
||||||
from a constant wrapper:</p>
|
|
||||||
|
|
||||||
<pre>void foo(int);<br>value_initialized<int> const x ;<br>foo(x);<br></pre>
|
|
||||||
|
|
||||||
<p>But notice that this conversion operator is to <code>T&</code> although
|
|
||||||
it is itself <code>const</code>. As a consequence, if <code>T</code> is
|
|
||||||
a non-<code>const</code> type, you can modify the wrapped object even from
|
|
||||||
within a constant wrapper:</p>
|
|
||||||
|
|
||||||
<pre>value_initialized<int> const x_c ;<br>int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const.<br>xr = 2 ; </pre>
|
|
||||||
|
|
||||||
<p>The reason for this obscure behavior is that some commonly used compilers
|
|
||||||
just don't accept the following valid code:</p>
|
|
||||||
|
|
||||||
<pre>struct X<br>{<br> operator int&() ;<br> operator int const&() const ; <br>};<br>X x ;<br>(x == 1 ) ; // ERROR HERE!</pre>
|
|
||||||
|
|
||||||
<p>These compilers complain about ambiguity between the conversion operators.
|
|
||||||
This complaint is incorrect, but the only workaround that I know of is
|
|
||||||
to provide only one of them, which leads to the obscure behavior just explained.<br>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Recommended practice: The non-member get() idiom</h3>
|
|
||||||
|
|
||||||
<p>The obscure behavior of being able to modify a non-<code>const</code>
|
|
||||||
wrapped object from within a constant wrapper can be avoided if access to
|
|
||||||
the wrapped object is always performed with the <code>get()</code> idiom:</p>
|
|
||||||
|
|
||||||
<pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
|
|
||||||
|
|
||||||
<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> </pre>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<p>Revised 19 September 2002</p>
|
|
||||||
|
|
||||||
<p>© 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>
|
|
@@ -1,119 +0,0 @@
|
|||||||
// (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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user