Compare commits

...

1 Commits

Author SHA1 Message Date
4300becb58 This commit was manufactured by cvs2svn to create branch 'SPIRIT_1_6'.
[SVN r23968]
2004-07-23 02:16:28 +00:00
15 changed files with 0 additions and 1737 deletions

View File

@ -1,168 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title> Collection Traits </title><meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"></head> <body><table ><tr ><td ><img src="cboost.gif" width="100%" border="0"></td><td ><h1 ><br> Collection Traits </h1></td></tr></table><ul ><li ><a href="#Introduction" >Introduction</a></li><li ><a href="#Reference" >Reference</a></li><ul ><li ><a href="#Synopsis" >Synopsis</a></li><li ><a href="#Library headers" >Library headers</a></li><li ><a href="#Semantics" >Semantics</a></li></ul><li ><a href="#Examples" >Examples</a></li><li ><a href="#Portability" >Portability</a></li><li ><a href="#FAQ" >FAQ</a></li><li ><a href="#History" >History</a></li></ul><hr size="1" ><h2 >Introduction</h2><a name="Introduction" ></a><p >This library makes it possible to treat different types as if they have
implemented a subset of the container requirements
(see &sect;23.1of the C++ standard). Formally, that subset is defined by
the <a href="Collection.htm" target="_self" >CollectionConcept.</a>
The subset deals mostly with
iterator returning functions and nested <code >typedef</code>s.
The main goal is to treat built-in arrays, standard containers,
pairs of iterators and some iterators uniformly. Formally, this library is an implementation
of the <a href="#ExternalCollectionConcept" >ExternalCollectionConcept</a> (see also this explanation of <a href="external_concepts.html" target="_self" >External Concepts</a> ).</p><p >The main advantages are <ul ><li >safe use of built-in arrays</li><li >simpler implementation of generic container algorithms</li><li >more flexible client code</li><li >correct handling of null-terminated strings</li></ul></p><p >Below are given a small example (the complete example can be found <a href="../test/algorithm_example.cpp" target="_self" >here</a> ):<pre >
//
// Example: extracting bounds in generic algorithms
//
template&lt; typename ExternalCollection, typename T &gt;
inline typename boost::iterator_of&lt;ExternalCollection&gt;::type
find( ExternalCollection& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
template&lt; typename ExternalCollection, typename T &gt;
inline typename boost::const_iterator_of&lt;ExternalCollection&gt;::type
find( const ExternalCollection& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
//
// replace first value and return its index
//
template&lt; typename EC, typename T &gt;
inline typename boost::size_type_of&lt; EC &gt;::type
my_generic_replace( EC& c, const T& value, const T& replacement )
{
typename boost::const_iterator_of&lt;EC&gt;::type found = find( c, value );
*found = replacement;
return std::distance( boost::begin( c ), found );
}
//
// usage
//
std::vector&lt;int&gt; my_vector;
typedef vector&lt;int&gt;::iterator iterator;
std::pair&lt;iterator,iterator&gt; my_view( my_vector.begin(), my_vector.begin() + N );
char str[] = "a string";
// ...
std::cout &lt;&lt; my_generic_replace( my_vector, 4, 2 )
&lt;&lt; my_generic_replace( my_view, 4, 2 )
&lt;&lt; my_generic_replace( str, 'a', 'b' );
</pre>By using the free-standing functions and type-generators, the code automatically
works for all the types supported by this library. Notice that we have to provide
two version of <code >find()</code> since we cannot
forward a non-const rvalue with reference arguments (see this article about <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_self" >The Forwarding Problem</a> ).</p><hr size="1" ><h2 >Reference</h2><a name="Reference" ></a><p ><pre >#include &lt;boost/collection_traits.hpp&gt;</pre></p><p >Five types of objects are currently supported by the library:<ul ><li >standard containers</li><li >built-in arrays</li><li >null terminated strings (this includes <code >char[]</code>,<code >wchar_t[]</code>,<code >char*</code>, and <code >wchar_t*</code>)</li><li ><code >std::pair&lt;iterator,iterator&gt;</code></li><li >iterators which when default constructed denotes the end of the range</li></ul>It is worth noticing that some functionality requires partial template specialization, in particular,
full array support does (remark: this is a very small problem since one would use <code>boost::array<></code>
anyway). Also note that arrays and pointers of <code >char</code> or <code >whar_t</code> are treated special because of their use in string algorithms.</p><h3 >ExternalCollectionConcept</h3><a name="ExternalCollectionConcept" ></a><p >The concept is defined by the type-generators and the
functions below. Even though these functions are defined in
namespace <code>boost</code>, there is no such general requirement, that is,
if one wants to extend the list of supported types, it can be done in any
namespace.</p><h3 >Synopsis</h3><a name="Synopsis" ></a><p ><pre>
namespace boost
{
//
// type generators
//
template< typename EC >
struct <a href="#value_type_of" >value_type_of</a>
{
typedef ... type; // type of stored objects
};
template< typename EC >
struct <a href="#iterator_of" >iterator_of</a>
{
typedef ... type; // iterator over stored objects
};
template< typename EC >
struct <a href="#const_iterator_of" >const_iterator_of</a>
{
typedef ... type; // iterator over immutable stored objects
};
template< typename EC >
struct <a href="#difference_type_of" >difference_type_of</a>
{
typedef ... type;
BOOST_STATIC_ASSERT( boost::is_signed< type >::value );
//
// remark: if std::iterator_traits<> works for the type, this assertion must hold
//
BOOST_STATIC_ASSERT( boost::is_same< type, std::iterator_traits< typename
<a href="#iterator_of" >iterator_of</a>< EC >::type >::difference_type>::value );
};
template< typename EC >
struct <a href="#size_type_of" >size_type_of</a>
{
typedef ... type;
BOOST_STATIC_ASSERT( boost::is_unsigned< type >::value );
BOOST_STATIC_ASSERT( sizeof( type ) >= sizeof( <a href="#difference_type_of" >difference_type_of</a>< EC >::type ) );
};
template< typename EC >
struct <a href="#result_iterator_of" >result_iterator_of</a>
{
typedef ... type;
// <a href="#iterator_of" >iterator_of</a>< EC >::type if EC is non-const, <a href="#const_iterator_of" >const_iterator_of</a>< EC >::type otherwise
};
//
// funtions
//
template< typename EC >
inline typename iterator_of<EC>::type
<a href="#begin" >begin</a>( EC& c );
template< typename EC >
inline typename const_iterator_of< EC >::type
<a href="#begin" >begin</a>( const EC& c );
template< typename EC >
inline typename iterator_of< EC >::type
<a href="#end" >end</a>( EC& c );
template< typename EC >
inline typename const_iterator_of< EC >::type
<a href="#end" >end</a>( const EC& c );
template< typename EC >
inline bool
<a href="#empty" >empty</a>( const EC& c );
template< typename EC >
inline typename size_type_of< EC >::type
<a href="#size" >size</a>( const EC& c );
} // namespace 'boost' </pre></p><h3 >Library headers</h3><a name="Library headers" ></a><table cellpadding=5 border=1 > <tr ><th >Header</th><th >Includes</th></tr><tr ><td ><code >&lt;boost/collection_traits.hpp&gt;</code></td><td >everything</td></tr><tr ><td ><code >&lt;boost/collection_traits/types.hpp&gt;</code></td><td >every type-generator</td></tr><tr ><td ><code >&lt;boost/collection_traits/functions.hpp&gt;</code></td><td >every function</td></tr><tr ><td ><code >&lt;boost/collection_traits/value_type.hpp&gt;</code></td><td ><a href="#value_type_of" >value_type_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/iterator.hpp&gt;</code></td><td ><a href="#iterator_of" >iterator_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/const_iterator.hpp&gt;</code></td><td ><a href="#const_iterator_of" >const_iterator_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/difference_type.hpp&gt;</code></td><td ><a href="#difference_type_of" >difference_type_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/size_type.hpp&gt;</code></td><td ><a href="#size_type_of" >size_type_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/result_iterator.hpp&gt;</code></td><td ><a href="#result_iterator_of" >result_iterator_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/begin.hpp&gt;</code></td><td ><a href="#begin" >begin</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/end.hpp&gt;</code></td><td ><a href="#end" >end</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/empty.hpp&gt;</code></td><td ><a href="#empty" >empty</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/size.hpp&gt;</code></td><td ><a href="#size" >size</a></td></tr> </table><br><h3 >Semantics</h3><a name="Semantics" ></a><p >In the table <code >C</code> is a type that conforms to the ExternalCollectionConcept and <code >c</code> is an object of that type.<code > SC</code> will denote a standard
container, <code > T[sz]</code> will denote an array of type <code >T</code> of size <code >sz</code>, <code >P</code> will denote <code >std::pair&lt;&gt;</code>, <code > I</code> means an iterator which default construction
denotes the end of the range and <code >sc,t,p,i</code> are objects of these types,
respectively. Special cases for <code >char*</code> and <code >wchar_t*</code> are described explicitly. </p><table border=1 cellpadding=5 > <tr ><th >Expression</th><th >Return type</th><th >Complexity</th></tr><tr ><a name="value_type_of" ></a><td ><code >value_type_of&lt;C&gt;::type</code></td><td ><code >SC::value_type</code><br><code >T</code><br><code >std::iterator_traits&lt;P::first_type&gt;::value_type</code><br><code >std::iterator_traits&lt;I&gt;::value_type</code></td><td >compile time</td></tr><tr ><a name="iterator_of" ></a><td ><code >iterator_of&lt;C&gt;::type</code></td><td ><code >SC::iterator</code><br><code >T*</code><br><code >P::first_type</code><br><code >I</code></td><td >compile time</td></tr><tr ><a name="const_iterator_of" ></a><td ><code >const_iterator_of&lt;C&gt;::type</code></td><td ><code >SC::const_iterator</code><br><code >const T*</code><br><code >P::first_type</code><br><code >I</code></td><td >compile time</td></tr><tr ><a name="difference_type_of" ></a><td ><code >difference_type_of&lt;C&gt;::type</code></td><td ><code >SC::difference_type</code><br><code >std::ptrdiff_t</code><br><code >std::iterator_traits&lt;P::first_type&gt;::difference_type</code><br><code >std::iterator_traits&lt;I&gt;::difference_type</code></td><td >compile time</td></tr><tr ><a name="size_type_of" ></a><td ><code >size_type_of&lt;C&gt;::type</code></td><td ><code >SC::size_type</code><br><code >std::size_t</code><br><code >std::size_t</code><br><code >std::size_t</code></td><td >compile time</td></tr><tr ><a name="result_iterator_of" ></a><td ><code >result_iterator_of&lt;C&gt;::type</code></td><td ><code >const_iterator_of&lt;C&gt;::type</code> if <code >C</code> is <code >const</code><br><code >iterator_of&lt;C&gt;::type</code> otherwise </td><td >compile time</td></tr> </table> <br> <table border=1 cellpadding=5 > <tr ><th >Expression</th><th >Return type</th><th >Effects</th><th >Complexity</th></tr><tr ><a name="begin" ></a><td ><code >begin( c )</code></td><td ><code >result_iterator_of&lt;C&gt;::type</code></td><td ><code >sc.begin()</code><br><code >t</code><br><code >p.first</code><br><code >i</code></td><td >constant time</td></tr><tr ><a name="end" ></a><td ><code >end( c )</code></td><td ><code >result_iterator_of&lt;C&gt;::type</code></td><td ><code >sc.end()</code><br><code >t + std::char_traits&lt;C&gt;::length( t )</code> if <code >C</code> is <code >char*</code> or <code >wchar_t*</code><br><code >t + sz - 1</code> if <code >C</code> is <code >char[sz]</code> or <code >wchar_t[sz]</code><br><code >t + sz</code> otherwise <br><code >p.second</code><br><code >I()</code></td><td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code><br>constant time otherwise</td></tr><tr ><a name="empty" ></a><td ><code >empty( c )</code></td><td >Convertible to <code >bool</code></td><td ><code >sc.empty()</code><br><code >size( t ) == 0</code><br><code >p.first == p.second</code><br><code >begin( i ) == end( i )</code></td><td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code><br>constant time otherwise<br></td></tr><tr ><a name="size" ></a><td ><code >size( c )</code></td><td ><code >size_type_of&lt;C&gt;::type</code></td><td ><code >sc.size()</code><br><code >end( t ) - begin( t )</code><br><code >distance( p.first, p.second )</code><br><code >not available for iterators</code></td><td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code><br> or if <code >std::distance()</code> is linear <br>constant time otherwise</td></tr> </table><p >Please note that <code >char*</code>,<code >whar_t*</code>,<code >char[]</code>, and <code >wchar_t[]</code> behaves differently from
normal arrays only for <code >size()</code> and <code >end()</code>.
Note that the null pointer is allowed as an argument in these cases.</p><br><hr size="1" ><h2 >Examples</h2><a name="Examples" ></a><p >Some examples are given in the accompanying test
files:</p><ul ><li > <a href="../test/iterator.cpp" target="_self" ><code >iterator.cpp</code></a> </li> shows how to implement a container version of <code >std::copy()</code> that works with <code >std::ifstream_iterator&lt;&gt;.</code><li > <a href="../test/string.cpp" target="_self" ><code >string.cpp</code></a> </li> shows how to implement a container version of <code >std::find()</code> that works with <code >char[],wchar_t[],char*,wchar_t*.</code><li > <a href="../test/algorithm_example.cpp" target="_self" ><code >algorithm_example.cpp</code></a> </li> shows the replace example from the introduction. </ul><hr size="1" ><h2 >Portability</h2><a name="Portability" ></a><p >Full support for built-in arrays require that the
compiler supports class template partial specialization.</p><p >Notice that some compilers cannot do function template ordering
properly. In that case one cannot rely of <code >result_iterator_of&lt;&gt;</code> and a single function definition; instead one needs to supply
a function overloaded for const and non-const arguments if it is required.</p><p >Full support for iterators like <code >std::istream_iterator&lt;&gt;</code> depends very
much on a conforming standard library.</p><p >Most of the tests have been run successfully on these compilers<ul ><li >vc7.1</li><li >gcc3.2</li><li >como4.3.0.1</li><li >bcc6</li></ul></p><hr size="1" ><h2 >FAQ</h2><a name="FAQ" ></a><ol ><li >Why is there no difference between <code >iterator_of&lt;C&gt;::type</code> and <code >const_iterator_of&lt;C&gt;::type</code> for <code >std::pair&lt;iterator,iterator&gt;</code> or iterators which default construction denotes the end of the range?</li><p >In general it is not possible nor desirable to find a corresponding <code >const_iterator</code>. When it is possible to come up with
one, the client might choose to
construct a <code >std::pair&lt;const_iterator,const_iterator&gt;</code> object. </p><li >Why does the traits not supply more types or more functions?<p >The traits class have been kept small because its current interface
will serve most purposes. If and when a genuine need arises for
more functionality, it can be implemented.</p></li><li >How should I implement generic algorithms for external collections?<p >One should always start with a generic algorithm that takes two iterators as input. Then use the
collection traits to build handier versions on top of the base algorithm.</p></li></ol><hr size="1" ><h2 >History</h2><a name="History" ></a><p >The library have been under way for a long time. Dietmar K<>hl originally
intended to submit an <code >array_traits&lt;&gt;</code> class template which had most
of the functionality present now, but only for arrays and standard containers.
Meanwhile work on container algorithms
in various context showed the need for handling pairs of iterators, and
string libraries needed special treatment of character arrays.
Thorsten Ottosen wrote everything from the ground up including the first
work-around for missing partial template specialization. Pavol Droba helped to
improve the work-around for handicapped compilers and the special character support.
The naming scheme of type-generators was suggested by Peter Dimov. </p><hr size="1" ><p >&copy; Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk).
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.</p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></body></html>
<!-- Copyright Dezide Aps 2003-2004 -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -1,38 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title> Concepts and External Concepts </title><meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"></head> <body><table ><tr ><td ><img src="cboost.gif" width="100%" border="0"></td><td ><h1 >Concepts and External Concepts</h1></td></tr></table><p >Generic programming in C++ is characterized by the use of function and class templates where
the template parameter(s) must satisfy certain requirements.Often these
requirements are so important that we give them a name: we call
such a set of type requirements a <b>concept</b>. We say that a type <i>
conforms to a concept</i> or that it <i>is a model of a concept</i> if it
satisfies all of those requirements. The concept can be specified as a set
of member functions with well-defined semantics
and a set of nested typedefs with well-defined properties.</p><p >Often it much more flexible to provide free-standing functions and typedefs
which provides the exact same semantics (but a different syntax) as
specified
by the concept. This allows generic code to treat different types <i> as if
</i> they fulfilled the concept. In this case we say that the concept has
been <b> externalized </b> or that the new requirements constitutes an <b>external
concept </b>. We say that a type <i> conforms to an external concept </i>
or that it <i> is a model of an external concept </i>. A concept may exist
without a corresponding external concept and conversely.</p><p >Whenever a concept specifies a member function, the corresponding external
concept
must specify a free-standing function of the same name, same return type and
the same argument list except there is an extra first argument which must
be of the type (or a reference to that type) that is to fulfill the external
concept. If the corresonding member function has any cv-qulifiers, the
first argument must have the same cv-qualifiers. Whenever a concept
specifies a nested typedef, the corresponding external concept
specifies a <b>type-generator</b>, that is, a type with a nested typedef
named <code>type</code>. The type-generator has the name as the nested typedef with
<code>_of</code> appended.
The converse relationship of an external concept and its corresponding concept
also holds.</p><p ><b ><i >Example:</i></b></p><p >A type <code>T</code> fulfills the FooConcept if it
has the follwing public members:</p><code> void T::foo( int ) const; <br>
int T::bar(); <br>
typedef <i>implementation defined </i> foo_type;</code><p >The corresponding external concept is the ExternalFooConcept.</p><p >A type <code>T</code> fullfills the ExternalFooConcept if these
free-standing functions and type-generators exists:</p><code>void foo( const T&, int ); <br>
int bar( T& ); <br>
foo_type_of< T >::type;</code> <br> <br><hr size="1" ><h3 >Literature</h3><ul ><li > <a href="http://www.boost.org/more/generic_programming.html#type_generator" target="_self" >Type Generators</a> </li><li > <a href="http://www.boost.org/more/generic_programming.html#concept" target="_self" >Concepts</a> </li><li > <a href="http://www.sgi.com/tech/stl/stl_introduction.html" target="_self" >Concepts and SGI STL</a> </li></ul><hr size="1" ><p >&copy; Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk).
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.</p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></body></html>
<!-- Copyright Dezide Aps 2003-2004 -->

View File

@ -1,612 +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">
<IMG SRC="cboost.gif"
ALT="C++ Boost">
<IMG SRC="/Images/stat.gif" ALT="" BORDER=0 WIDTH = "6" HEIGHT = "6" >
<BR Clear>
<H1>Collection</H1>
<h3>Description</h3>
A Collection is a <i>concept</i> similar to the STL <a
href="http://www.sgi.com/Technology/STL/Container.html">Container</a>
concept. A Collection provides iterators for accessing a range of
elements and provides information about the number of elements in the
Collection. However, a Collection has fewer requirements than a
Container. The motivation for the Collection concept is that there are
many useful Container-like types that do not meet the full
requirements of Container, and many algorithms that can be written
with this reduced set of requirements. To summarize the reduction
in requirements:
<UL>
<LI>It is not required to &quot;own&quot; its elements: the lifetime
of an element in a Collection does not have to match the lifetime of
the Collection object, though the lifetime of the element should cover
the lifetime of the Collection object.
<LI>The semantics of copying a Collection object is not defined (it
could be a deep or shallow copy or not even support copying).
<LI>The associated reference type of a Collection does
not have to be a real C++ reference.
</UL>
Because of the reduced requirements, some care must be taken when
writing code that is meant to be generic for all Collection types.
In particular, a Collection object should be passed by-reference
since assumptions can not be made about the behaviour of the
copy constructor.
<p>
<h3>Associated types</h3>
<Table border>
<TR>
<TD VAlign=top>
Value type
</TD>
<TD VAlign=top>
<tt>X::value_type</tt>
</TD>
<TD VAlign=top>
The type of the object stored in a Collection.
If the Collection is <i>mutable</i> then
the value type must be <A
href="http://www.sgi.com/Technology/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/Technology/STL/InputIterator.html">InputIterator</A>.
</TD>
</TR>
<TR>
<TD VAlign=top>
Const iterator type
</TD>
<TD VAlign=top>
<tt>X::const_iterator</tt>
</TD>
<TD VAlign=top>
A type of iterator that may be used to examine, but not to modify,
a Collection's elements.
</TD>
</TR>
<TR>
<TD VAlign=top>
Reference type
</TD>
<TD VAlign=top>
<tt>X::reference</tt>
</TD>
<TD VAlign=top>
A type that behaves like a reference to the Collection's value type.
<a href="#1">[1]</a>
</TD>
</TR>
<TR>
<TD VAlign=top>
Const reference type
</TD>
<TD VAlign=top>
<tt>X::const_reference</tt>
</TD>
<TD VAlign=top>
A type that behaves like a const reference to the Collection's value type.
</TD>
</TR>
<TR>
<TD VAlign=top>
Pointer type
</TD>
<TD VAlign=top>
<tt>X::pointer</tt>
</TD>
<TD VAlign=top>
A type that behaves as a pointer to the Collection's value type.
</TD>
</TR>
<TR>
<TD VAlign=top>
Distance type
</TD>
<TD VAlign=top>
<tt>X::difference_type</tt>
</TD>
<TD VAlign=top>
A signed integral type used to represent the distance between two
of the Collection's iterators. This type must be the same as
the iterator's distance type.
</TD>
</TR>
<TR>
<TD VAlign=top>
Size type
</TD>
<TD VAlign=top>
<tt>X::size_type</tt>
</TD>
<TD VAlign=top>
An unsigned integral type that can represent any nonnegative value
of the Collection's distance type.
</TD>
</tr>
</table>
<h3>Notation</h3>
<Table>
<TR>
<TD VAlign=top>
<tt>X</tt>
</TD>
<TD VAlign=top>
A type that is a model of Collection.
</TD>
</TR>
<TR>
<TD VAlign=top>
<tt>a</tt>, <tt>b</tt>
</TD>
<TD VAlign=top>
Object of type <tt>X</tt>.
</TD>
</TR>
<TR>
<TD VAlign=top>
<tt>T</tt>
</TD>
<TD VAlign=top>
The value type of <tt>X</tt>.
</TD>
</tr>
</table>
<h3>Valid expressions</h3>
The following expressions must be valid.
<p>
<Table border>
<TR>
<TH>
Name
</TH>
<TH>
Expression
</TH>
<TH>
Return type
</TH>
</TR>
<TR>
<TD VAlign=top>
Beginning of range
</TD>
<TD VAlign=top>
<tt>a.begin()</tt>
</TD>
<TD VAlign=top>
<tt>iterator</tt> if <tt>a</tt> is mutable, <tt>const_iterator</tt> otherwise
</TD>
</TR>
<TR>
<TD VAlign=top>
End of range
</TD>
<TD VAlign=top>
<tt>a.end()</tt>
</TD>
<TD VAlign=top>
<tt>iterator</tt> if <tt>a</tt> is mutable, <tt>const_iterator</tt> otherwise
</TD>
</TR>
<TR>
<TD VAlign=top>
Size
</TD>
<TD VAlign=top>
<tt>a.size()</tt>
</TD>
<TD VAlign=top>
<tt>size_type</tt>
</TD>
</TR>
<!--
<TR>
<TD VAlign=top>
Maximum size
</TD>
<TD VAlign=top>
<tt>a.max_size()</tt>
</TD>
<TD VAlign=top>
<tt>size_type</tt>
</TD>
</TR>
<TR>
-->
<TD VAlign=top>
Empty Collection
</TD>
<TD VAlign=top>
<tt>a.empty()</tt>
</TD>
<TD VAlign=top>
Convertible to <tt>bool</tt>
</TD>
</TR>
<TR>
<!--
<TD VAlign=top>
Swap
</TD>
<TD VAlign=top>
<tt>a.swap(b)</tt>
</TD>
<TD VAlign=top>
<tt>void</tt>
</TD> -->
</tr>
</table>
<h3>Expression semantics</h3>
<Table border>
<TR>
<TH>
Name
</TH>
<TH>
Expression
</TH>
<TH>
Semantics
</TH>
<TH>
Postcondition
</TH>
</TR>
<TD VAlign=top>
<TR>
<TD VAlign=top>
Beginning of range
</TD>
<TD VAlign=top>
<tt>a.begin()</tt>
</TD>
<TD VAlign=top>
Returns an iterator pointing to the first element in the Collection.
</TD>
<TD VAlign=top>
<tt>a.begin()</tt> is either dereferenceable or past-the-end. It is
past-the-end if and only if <tt>a.size() == 0</tt>.
</TD>
</TR>
<TR>
<TD VAlign=top>
End of range
</TD>
<TD VAlign=top>
<tt>a.end()</tt>
</TD>
<TD VAlign=top>
Returns an iterator pointing one past the last element in the
Collection.
</TD>
<TD VAlign=top>
<tt>a.end()</tt> is past-the-end.
</TD>
</TR>
<TR>
<TD VAlign=top>
Size
</TD>
<TD VAlign=top>
<tt>a.size()</tt>
</TD>
<TD VAlign=top>
Returns the size of the Collection, that is, its number of elements.
</TD>
<TD VAlign=top>
<tt>a.size() &gt;= 0
</TD>
</TR>
<!--
<TR>
<TD VAlign=top>
Maximum size
</TD>
<TD VAlign=top>
<tt>a.max_size()</tt>
</TD>
<TD VAlign=top>
&nbsp;
</TD>
<TD VAlign=top>
Returns the largest size that this Collection can ever have. <A href="#8">[8]</A>
</TD>
<TD VAlign=top>
<tt>a.max_size() &gt;= 0 &amp;&amp; a.max_size() &gt;= a.size()</tt>
</TD>
</TR>
-->
<TR>
<TD VAlign=top>
Empty Collection
</TD>
<TD VAlign=top>
<tt>a.empty()</tt>
</TD>
<TD VAlign=top>
Equivalent to <tt>a.size() == 0</tt>. (But possibly faster.)
</TD>
<TD VAlign=top>
&nbsp;
</TD>
</TR>
<TR>
<!--
<TD VAlign=top>
Swap
</TD>
<TD VAlign=top>
<tt>a.swap(b)</tt>
</TD>
<TD VAlign=top>
Equivalent to <tt>swap(a,b)</tt>
</TD>
<TD VAlign=top>
&nbsp;
</TD>
-->
</tr>
</table>
<h3>Complexity guarantees</h3>
<tt>begin()</tt> and <tt>end()</tt> are amortized constant time.
<P>
<tt>size()</tt> is at most linear in the Collection's
size. <tt>empty()</tt> is amortized constant time.
<!-- <P>
<tt>swap()</tt> is at most linear in the size of the two collections. -->
<h3>Invariants</h3>
<Table border>
<TR>
<TD VAlign=top>
Valid range
</TD>
<TD VAlign=top>
For any Collection <tt>a</tt>, <tt>[a.begin(), a.end())</tt> is a valid
range.
</TD>
</TR>
<TR>
<TD VAlign=top>
Range size
</TD>
<TD VAlign=top>
<tt>a.size()</tt> is equal to the distance from <tt>a.begin()</tt> to <tt>a.end()</tt>.
</TD>
</TR>
<TR>
<TD VAlign=top>
Completeness
</TD>
<TD VAlign=top>
An algorithm that iterates through the range <tt>[a.begin(), a.end())</tt>
will pass through every element of <tt>a</tt>.
</TD>
</tr>
</table>
<h3>Models</h3>
<UL>
<!-- <LI> <tt>array</tt> -->
<!--<LI> <tt>array_ptr</tt> -->
<LI> <tt>vector&lt;bool&gt;</tt>
</UL>
<!--
<h3>Collection Refinements</h3>
There are quite a few concepts that refine the Collection concept,
similar to the concepts that refine the Container concept. Here
is a brief overview of the refining concepts.
<h4>ForwardCollection</h4>
The elements are arranged in some order that
does not change spontaneously from one iteration to the next. As
a result, a ForwardCollection is
<A
href="http://www.sgi.com/Technology/STL/EqualityComparable.html">EqualityComparable</A>
and
<A
href="http://www.sgi.com/Technology/STL/LessThanComparable.html">LessThanComparable</A>.
In addition, the iterator type of a ForwardCollection is a
MultiPassInputIterator which is just an InputIterator with the added
requirements that the iterator can be used to make multiple passes
through a range, and that if <tt>it1 == it2</tt> and <tt>it1</tt> is
dereferenceable then <tt>++it1 == ++it2</tt>. The ForwardCollection
also has a <tt>front()</tt> method.
<p>
<Table border>
<TR>
<TH>
Name
</TH>
<TH>
Expression
</TH>
<TH>
Return type
</TH>
<TH>
Semantics
</TH>
</TR>
<TR>
<TD VAlign=top>
Font
</TD>
<TD VAlign=top>
<tt>a.front()</tt>
</TD>
<TD VAlign=top>
<tt>reference</tt> if <tt>a</tt> is mutable, <br> <tt>const_reference</tt>
otherwise.
</TD>
<TD VAlign=top>
Equivalent to <tt>*(a.first())</tt>.
</TD>
</TR>
</table>
<h4>ReversibleCollection</h4>
The container provides access to iterators that traverse in both
directions (forward and reverse). The iterator type must meet all of
the requirements of <a
href="http://www.sgi.com/Technology/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.
-->
<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). 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/Technology/STL/Container.html">Container</A>
<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>, Univ.of Notre Dame and C++ Library & Compiler Group/SGI (<A HREF="mailto:jsiek@engr.sgi.com">jsiek@engr.sgi.com</A>)
</TD></TR>
<tr >
<TD nowrap>Copyright &copy 2004</TD><TD>
Thorsten Ottosen.
</TABLE>
</BODY>
</HTML>

View File

@ -1,8 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title> Collection Traits </title><meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"></head>
<FRAMESET cols="100%">
<frame src="doc/collection_traits.html" >
</FRAMESET>
</HTML>

View File

@ -1,59 +0,0 @@
subproject libs/range/test ;
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ;
DEPENDS all : test ;
{
test-suite range
: [ run
array.cpp
: :
:
: array_test
]
[ run
iterator_pair.cpp
: :
:
: iterator_pair_test
]
[ run
std_container.cpp
: :
:
: std_container_test
]
[ run
string.cpp
: :
:
: string_test
]
[ run
iterator_range.cpp
: :
:
: iterator_range
]
[ run
partial_workaround.cpp
: :
:
: workaround_test
]
[ run
algorithm_example.cpp
: :
:
: example_test
]
[ run
reversible_range.cpp
: :
:
: reversible_range_test
] ;
}

View File

@ -1,86 +0,0 @@
1. ok. I should add something about extending the lib + how to rely on ADL.
2. | I'd prefer "primary specialization" to "default" in the comments.
ok. Is that the correct term?
3. A "specialization" of a template is the result of instantiating
it, so the more accurate term, as given in Vandevoorde and
Josuttis, is "primary template."
5. new intro:
"When writing generic code that works with Standard Library
containers, one often finds it desirable to extend that code to
work with other types that offer enough functionality to satisfy
the needs of the generic code, but in an altered form. For
example, raw arrays are often suitable for use with generic code
that works with containers, provided a suitable adapter is used.
Likewise, null terminated strings can be treated as containers of
characters, if suitably adapted. This library provides the means
to adapt Standard Library containers, null terminated strings,
std::pairs of iterators, and raw arrays, such that the same
generic code can work with them all."
6. > | The Introduction is missing discussion of the use of namespace
> | scope functions to do what heretofore would be done via member
> | functions. Instead, the example and the sentence immediately
> | following it imply this change of syntax.
>
> Wouldn't it only duplicate stuff in the two links to CollectionCocept and ExternalConcepts?
In a sense, yes, but what I'm proposing is a much abbreviated
form:
"To allow generic code to work with objects that conform to the
ExternalCollectionConcept, this library provides a set of
namespace scope functions and <A
href="http://www.boost.org/more/generic_programming.html#type_generator">type
generators</A> that provide a standard interface for the required
functionality. Whereas one might write, "c.end()," to get the end
iterator from a Standard Library container, c, using this
library, it would be written, "boost::end(c)." This change in
syntax is necessary to make the same interface possible with the
other supported types such as null terminated strings."
7. [boost-book-style]I like colors, so perhaps use the boost-book stylesheets?
9. New range explanation:
I'd say "Iterable" if we have to use an "-able" term. 24.1/7
suggests to me that "Range" might be OK:
Most of the library's algorithmic templates that operate on data
structures have interfaces that use ranges. A range is a pair of
iterators that designate the beginning and end of the computation. A
range [i, i) is an empty range; in general, a range [i, j) refers to
the elements in the data structure starting with the one pointed to
by i and up to but not including the one pointed to by j. Range [i,
j) is valid if and only if j is reachable from i. The result of the
application of functions in the library to invalid ranges is
undefined.
10. Don't make empty part of the Range concept, but have a default
implementation begin() == end() + spccial treatment of char*,
11. documentation: table with entities before other tables
12. Example of how result_iterator is used, necessary:
when designing templated classes
template<class container> struct widget {
typedef result_iterator_of<container> iterator;
};
13. better external concepts: Thorsten Ottosen wrote:
>> The documentation that's provided I found
>> sufficient, it's just of a different style than other concept
>> documentation.
>
> ok. I don't think the definition of concepts are that much more
> elaborate. What could be
> much better is the example which could follow normal concept
> standards. Is that what you had in mind?
Yes.
14. Change example code for my_generic_replace.
15. More concepts: random-access range: which have constant
time size(); Cpm matthews latest article.

View File

@ -1,65 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range.hpp>
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
namespace
{
template< typename ExternalCollection, typename T >
inline typename boost::iterator_of<ExternalCollection>::type
find( ExternalCollection& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
template< typename ExternalCollection, typename T >
inline typename boost::const_iterator_of<ExternalCollection>::type
find( const ExternalCollection& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
//
// replace first value and return its index
//
template< typename EC, typename T >
inline typename boost::size_type_of< EC >::type
my_generic_replace( EC& c, const T& value, const T& replacement )
{
typename boost::iterator_of<EC>::type found = find( c, value );
if( found != boost::end( c ) )
*found = replacement;
return std::distance( boost::begin( c ), found );
}
}
int main()
{
const int N = 5;
int v[] = { 1,2,3,4,5,6,6,7,8,9 };
std::vector<int> my_vector;
my_vector.assign( boost::begin( v ), boost::end( v ) );
typedef std::vector<int>::iterator iterator;
std::pair<iterator,iterator> my_view( boost::begin( my_vector ),
boost::begin( my_vector ) + N );
char str[] = "a string";
std::cout << my_generic_replace( my_vector, 4, 2 )
<< my_generic_replace( my_view, 4, 2 )
<< my_generic_replace( str, 'a', 'b' );
return 0;
}

View File

@ -1,81 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <iostream>
// This should be included before "using namespace boost",
// otherwise gcc headers will be confused with boost::iterator
// namespace.
#include <boost/test/included/unit_test_framework.hpp>
using namespace boost;
using namespace std;
void check_array()
{
const int sz = 9;
typedef int array_t[sz];
int my_array[sz] = { 1,2,3,4,5,6,7,8,9 };
const array_t ca = { 1,2,3,4,5,6,7,8,10 };
#ifndef BOOST_CT_NO_STATIC_ASSERT
BOOST_STATIC_ASSERT(( is_same< value_type_of<array_t>::type, int >::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<array_t>::type, int* >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<array_t>::type, const int* >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<array_t>::type, std::ptrdiff_t >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<array_t>::type, std::size_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<array_t>::type, int* >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const array_t>::type, const int* >::value ));
BOOST_STATIC_ASSERT(( is_same< value_type_of<const array_t>::type, const int >::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<const array_t>::type, const int* >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<const array_t>::type, const int* >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<const array_t>::type, std::ptrdiff_t >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<const array_t>::type, std::size_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const array_t>::type, const int* >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const array_t>::type, const int* >::value ));
#endif
//typedef container<const array_t>::result_iterator iter;
//cout << typeid( iter() ).name() << endl;
BOOST_CHECK_EQUAL( begin( my_array ), my_array );
BOOST_CHECK_EQUAL( end( my_array ), my_array + size( my_array ) );
BOOST_CHECK_EQUAL( empty( my_array ), false );
//BOOST_CHECK( size( my_array ) == sizeof( sizer( my_array ) ) );
BOOST_CHECK_EQUAL( begin( ca ), ca );
BOOST_CHECK_EQUAL( end( ca ), ca + size( ca ) );
BOOST_CHECK_EQUAL( empty( ca ),false );
//BOOST_CHECK( size( ca ) == sizeof( sizer( ca ) ) );
}
using boost::unit_test_framework::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_array ) );
return test;
}

View File

@ -1,92 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <vector>
using namespace boost;
using boost::unit_test_framework::test_suite;
void check_iterator_pair()
{
typedef std::vector<int> vec_t;
vec_t vec;
vec.push_back( 4 );
typedef std::pair<vec_t::iterator,vec_t::iterator>
pair_t;
typedef std::pair<vec_t::const_iterator,vec_t::const_iterator>
const_pair_t;
typedef const pair_t const_pair_tt;
pair_t pair = std::make_pair( begin( vec ), end( vec ) );
const_pair_t const_pair = std::make_pair( begin( vec ), end( vec ) );
const_pair_tt constness_pair( pair );
BOOST_STATIC_ASSERT(( is_same< value_type_of<pair_t>::type,
detail::iterator_traits<pair_t::first_type>::value_type>::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<pair_t>::type, pair_t::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<pair_t>::type, pair_t::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<pair_t>::type,
detail::iterator_traits<pair_t::first_type>::difference_type >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<pair_t>::type, std::size_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<pair_t>::type, pair_t::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const_pair_t>::type, const_pair_t::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< value_type_of<const_pair_tt>::type,
detail::iterator_traits<const_pair_t::first_type>::value_type>::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<const_pair_tt>::type, const_pair_tt::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<const_pair_tt>::type, const_pair_tt::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<const_pair_tt>::type,
detail::iterator_traits<const_pair_tt::first_type>::difference_type >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<const_pair_tt>::type, std::size_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const_pair_tt>::type, const_pair_tt::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const_pair_tt>::type, const_pair_tt::first_type >::value ));
BOOST_CHECK( begin( pair ) == pair.first );
BOOST_CHECK( end( pair ) == pair.second );
BOOST_CHECK( empty( pair ) == (pair.first == pair.second) );
BOOST_CHECK( size( pair ) == std::size_t( std::distance( pair.first, pair.second ) ) );
BOOST_CHECK( begin( const_pair ) == const_pair.first );
BOOST_CHECK( end( const_pair ) == const_pair.second );
BOOST_CHECK( empty( const_pair ) == (const_pair.first == const_pair.second) );
BOOST_CHECK( size( const_pair ) == std::size_t( std::distance( const_pair.first, const_pair.second ) ) );
BOOST_CHECK( begin( constness_pair ) == constness_pair.first );
BOOST_CHECK( end( constness_pair ) == constness_pair.second );
BOOST_CHECK( empty( constness_pair ) == (constness_pair.first == const_pair.second) );
BOOST_CHECK( size( constness_pair ) == std::size_t( std::distance( constness_pair.first, constness_pair.second ) ) );
}
#include <boost/test/included/unit_test_framework.hpp>
using boost::unit_test_framework::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_iterator_pair ) );
return test;
}

View File

@ -1,99 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range/iterator_range.hpp>
#include <boost/range/sub_range.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <iostream>
#include <string>
// This should be included before "using namespace boost",
// otherwise gcc headers will be confused with boost::iterator
// namespace.
#include <boost/test/included/unit_test_framework.hpp>
using namespace boost;
using namespace std;
struct add_one
{
template< class T >
T operator()( T r ) const
{
return r + 1;
}
};
void check_iterator_range()
{
typedef string::iterator iterator;
typedef string::const_iterator const_iterator;
typedef iterator_range<iterator> irange;
typedef iterator_range<const_iterator> cirange;
string str = "hello world";
const string cstr = "const world";
irange r = make_iterator_range( str );
r = make_iterator_range( str.begin(), str.end() );
cirange r2 = make_iterator_range( cstr );
r2 = make_iterator_range( cstr.begin(), cstr.end() );
r2 = make_iterator_range( str );
typedef sub_range<string> srange;
typedef sub_range<const string> csrange;
srange s = r;
BOOST_CHECK( r == s );
s = make_iterator_range( str );
csrange s2 = r;
s2 = r2;
s2 = make_iterator_range( cstr );
BOOST_CHECK( r != s2 );
s2 = make_iterator_range( str );
BOOST_CHECK( r.begin() == s.begin() );
BOOST_CHECK( r2.begin()== s2.begin() );
BOOST_CHECK( r.end() == s.end() );
BOOST_CHECK( r2.end() == s2.end() );
BOOST_CHECK_EQUAL( r.size(), s.size() );
BOOST_CHECK_EQUAL( r2.size(), s2.size() );
if( !r )
BOOST_CHECK( false );
if( !r2 )
BOOST_CHECK( false );
if( !s )
BOOST_CHECK( false );
if( !s2 )
BOOST_CHECK( false );
cout << r << r2 << s << s2;
string res = copy_range<string>( r );
BOOST_CHECK( equal( res.begin(), res.end(), r.begin() ) );
string res2 = transform_range<string>( s2, add_one() );
BOOST_CHECK( !equal( s2.begin(), s2.end(), res2.begin() ) );
}
using boost::unit_test_framework::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_iterator_range ) );
return test;
}

View File

@ -1,106 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 1
#include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/range/size_type.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/difference_type.hpp>
#include <boost/range/result_iterator.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/size.hpp>
#include <boost/range/empty.hpp>
#include <boost/range/detail/sfinae.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <iostream>
#include <vector>
using namespace boost;
using namespace std;
void check_partial_workaround()
{
using namespace range_detail;
using type_traits::yes_type;
using type_traits::no_type;
//////////////////////////////////////////////////////////////////////
// string
//////////////////////////////////////////////////////////////////////
char* c_ptr;
const char* cc_ptr;
wchar_t* w_ptr;
const wchar_t* cw_ptr;
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( c_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( cc_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( w_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( cw_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_char_ptr_impl( c_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( no_type ) == sizeof( is_char_ptr_impl( cc_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_wchar_t_ptr_impl( w_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( no_type ) == sizeof( is_wchar_t_ptr_impl( cw_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_char_ptr_impl( c_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_char_ptr_impl( cc_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_wchar_t_ptr_impl( w_ptr ) ) );
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_wchar_t_ptr_impl( cw_ptr ) ) );
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_container_,
boost::range_detail::range< vector<int> >::type >::value ));
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_pair_,
boost::range_detail::range< pair<int,int> >::type >::value ));
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::array_,
boost::range_detail::range< int[42] >::type >::value ));
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::char_ptr_,
boost::range_detail::range< char* >::type >::value ));
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::const_char_ptr_,
boost::range_detail::range< const char* >::type >::value ));
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::wchar_t_ptr_,
boost::range_detail::range< wchar_t* >::type >::value ));
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::const_wchar_t_ptr_,
boost::range_detail::range< const wchar_t* >::type >::value ));
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_container_,
boost::range_detail::range< vector<int> >::type >::value ));
}
#include <boost/test/included/unit_test_framework.hpp>
using boost::unit_test_framework::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_partial_workaround ) );
return test;
}

View File

@ -1,97 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range/rbegin.hpp>
#include <boost/range/rend.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <vector>
#include <algorithm>
using namespace boost;
using namespace std;
void check_iterator()
{
typedef vector<char> vec_t;
typedef vec_t::iterator iterator;
typedef pair<iterator,iterator> pair_t;
typedef reverse_iterator_of<pair_t>::type rev_iterator;
typedef pair<rev_iterator,rev_iterator> rev_pair_t;
vec_t vec;
pair_t p = make_pair( vec.begin(), vec.end() );
rev_pair_t rp = make_pair( rbegin( p ), rend( p ) );
char* str = "mutable";
const char* cstr = "not mutable";
char a[] = "mutable";
const char ca[] = "not mutable";
wchar_t* wstr = L"mutable";
const wchar_t* cwstr= L"not mutable";
wchar_t wa[] = L"mutable";
const wchar_t cwa[]= L"not mutable";
BOOST_CHECK( rbegin( vec ) == reverse_iterator_of<vec_t>::type( vec.end() ) );
BOOST_CHECK( rend( vec ) == reverse_iterator_of<vec_t>::type( vec.begin() ) );
BOOST_CHECK( distance( rbegin( vec ), rend( vec ) ) == distance( begin( vec ), end( vec ) ) );
BOOST_CHECK( rbegin( p ) == begin( rp ) );
BOOST_CHECK( rend( p ) == end( rp ) );
BOOST_CHECK( distance( rbegin( p ), rend( p ) ) == distance( begin( rp ), end( rp ) ) );
BOOST_CHECK( distance( begin( p ), end( p ) ) == distance( rbegin( rp ), rend( rp ) ) );
BOOST_CHECK_EQUAL( &*begin( str ), &*( rend( str ) - 1 ) );
BOOST_CHECK_EQUAL( &*( end( str ) - 1 ), &*rbegin( str ) );
BOOST_CHECK_EQUAL( &*begin( cstr ), &*( rend( cstr ) - 1 ) );
BOOST_CHECK_EQUAL( &*( end( cstr ) - 1 ), &*rbegin( cstr ) );
BOOST_CHECK_EQUAL( &*begin( a ), &*( rend( a ) - 1 ) );
BOOST_CHECK_EQUAL( &*( end( a ) - 1 ), &*rbegin( a ) );
BOOST_CHECK_EQUAL( &*begin( ca ), &*( rend( ca ) - 1 ) );
BOOST_CHECK_EQUAL( &*( end( ca ) - 1 ), &*rbegin( ca ) );
BOOST_CHECK_EQUAL( &*begin( wstr ), &*( rend( wstr ) - 1 ) );
BOOST_CHECK_EQUAL( &*( end( wstr ) - 1 ), &*rbegin( wstr ) );
BOOST_CHECK_EQUAL( &*begin( cwstr ), &*( rend( cwstr ) - 1 ) );
BOOST_CHECK_EQUAL( &*( end( cwstr ) - 1 ), &*rbegin( cwstr ) );
BOOST_CHECK_EQUAL( &*begin( wa ), &*( rend( wa ) - 1 ) );
BOOST_CHECK_EQUAL( &*( end( wa ) - 1 ), &*rbegin( wa ) );
BOOST_CHECK_EQUAL( &*begin( cwa ), &*( rend( cwa ) - 1 ) );
BOOST_CHECK_EQUAL( &*( end( cwa ) - 1 ), &*rbegin( cwa ) );
}
#include <boost/test/included/unit_test_framework.hpp>
using boost::unit_test_framework::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_iterator ) );
return test;
}

View File

@ -1,74 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <vector>
using namespace boost;
using boost::unit_test_framework::test_suite;
void check_std_container()
{
typedef std::vector<int> vec_t;
vec_t vec;
vec.push_back( 3 ); vec.push_back( 4 );
const vec_t cvec( vec );
BOOST_STATIC_ASSERT(( is_same< value_type_of<vec_t>::type, vec_t::value_type >::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<vec_t>::type, vec_t::iterator >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<vec_t>::type, vec_t::const_iterator >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<vec_t>::type, vec_t::difference_type >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<vec_t>::type, vec_t::size_type >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<vec_t>::type, vec_t::iterator >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const vec_t>::type, vec_t::const_iterator >::value ));
BOOST_STATIC_ASSERT(( is_same< value_type_of<const vec_t>::type, vec_t::value_type >::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<const vec_t>::type, vec_t::iterator >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<const vec_t>::type, vec_t::const_iterator >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<const vec_t>::type, vec_t::difference_type >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<const vec_t>::type, vec_t::size_type >::value ));
BOOST_CHECK( begin( vec ) == vec.begin() );
BOOST_CHECK( end( vec ) == vec.end() );
BOOST_CHECK( empty( vec ) == vec.empty() );
BOOST_CHECK( size( vec ) == vec.size() );
BOOST_CHECK( begin( cvec ) == cvec.begin() );
BOOST_CHECK( end( cvec ) == cvec.end() );
BOOST_CHECK( empty( cvec ) == cvec.empty() );
BOOST_CHECK( size( cvec ) == cvec.size() );
}
#include <boost/test/included/unit_test_framework.hpp>
using boost::unit_test_framework::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_std_container ) );
return test;
}

View File

@ -1,152 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#include <boost/range.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/config.hpp>
#include <vector>
#include <fstream>
#include <algorithm>
template< typename Container, typename T >
BOOST_DEDUCED_TYPENAME boost::iterator_of<Container>::type
find( Container& c, T value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
template< typename Container, typename T >
BOOST_DEDUCED_TYPENAME boost::const_iterator_of<Container>::type
find( const Container& c, T value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
std::vector<char>
check_rvalue_return()
{
return std::vector<char>( 10, 'm' );
}
using namespace boost;
void check_char()
{
typedef char* char_iterator_t;
typedef char char_array_t[10];
const char* char_s = "a string";
char my_string[] = "another string";
const unsigned my_string_length = 14;
BOOST_STATIC_ASSERT(( is_same< value_type_of<char_iterator_t>::type,
detail::iterator_traits<char_iterator_t>::value_type>::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<char_iterator_t>::type, char_iterator_t >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<char_iterator_t>::type, const char* >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<char_iterator_t>::type,
::std::ptrdiff_t >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<char_iterator_t>::type, std::size_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<char_iterator_t>::type, char_iterator_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const char*>::type, const char* >::value ));
//
// note: why does is_same< result_iterator<const char_iterator_t>::type, const char* >::value
// fail?!?
BOOST_STATIC_ASSERT(( is_same< value_type_of<char_array_t>::type,
char>::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<char_array_t>::type, char* >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<char_array_t>::type, const char* >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<char_array_t>::type,
::std::ptrdiff_t >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<char_array_t>::type, std::size_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<char_array_t>::type, char* >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const char_array_t>::type, const char* >::value ));
BOOST_CHECK_EQUAL( begin( char_s ), char_s );
const char* end1 = begin( char_s ) + size( char_s );
BOOST_CHECK_EQUAL( end( char_s ), end1 );
BOOST_CHECK_EQUAL( empty( char_s ), (char_s == 0 || char_s[0] == char()) );
BOOST_CHECK_EQUAL( size( char_s ), std::char_traits<char>::length( char_s ) );
BOOST_CHECK_EQUAL( begin( my_string ), my_string );
const char* end2 = begin( my_string ) + size( my_string );
BOOST_CHECK_EQUAL( end( my_string ), end2 );
BOOST_CHECK_EQUAL( empty( my_string ), (my_string == 0 || my_string[0] == char()) );
BOOST_CHECK_EQUAL( size( my_string ), my_string_length );
BOOST_CHECK_EQUAL( size( my_string ), std::char_traits<char>::length( my_string ) );
char to_search = 'n';
BOOST_CHECK( find( char_s, to_search ) != end( char_s ) );
BOOST_CHECK( find( my_string, to_search ) != end( my_string ) );
}
void check_string()
{
check_char();
// check_char<volatile char>();
// check_char<const char>();
// check_char<const volatile char>();
#ifndef BOOST_NO_STD_WSTRING
typedef wchar_t* wchar_iterator_t;
const wchar_t* char_ws = L"a wide string";
wchar_t my_wstring[] = L"another wide string";
BOOST_STATIC_ASSERT(( is_same< value_type_of<wchar_iterator_t>::type,
detail::iterator_traits<wchar_iterator_t>::value_type>::value ));
BOOST_STATIC_ASSERT(( is_same< iterator_of<wchar_iterator_t>::type, wchar_iterator_t >::value ));
BOOST_STATIC_ASSERT(( is_same< const_iterator_of<wchar_iterator_t>::type, const wchar_t* >::value ));
BOOST_STATIC_ASSERT(( is_same< difference_type_of<wchar_iterator_t>::type,
detail::iterator_traits<wchar_iterator_t>::difference_type >::value ));
BOOST_STATIC_ASSERT(( is_same< size_type_of<wchar_iterator_t>::type, std::size_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<wchar_iterator_t>::type, wchar_iterator_t >::value ));
BOOST_STATIC_ASSERT(( is_same< result_iterator_of<const wchar_t*>::type, const wchar_t* >::value ));
BOOST_CHECK_EQUAL( begin( char_ws ), char_ws );
BOOST_CHECK_EQUAL( end( char_ws ), (begin( char_ws ) + size( char_ws )) );
BOOST_CHECK_EQUAL( empty( char_ws ), (char_ws == 0 || char_ws[0] == wchar_t()) );
BOOST_CHECK_EQUAL( size( char_ws ), std::char_traits<wchar_t>::length( char_ws ) );
wchar_t to_search = L'n';
BOOST_CHECK( find( char_ws, to_search ) != end( char_ws ) );
BOOST_CHECK( find( my_wstring, to_search ) != end( my_wstring ) );
#endif
find( check_rvalue_return(), 'n' );
}
#include <boost/test/included/unit_test_framework.hpp>
using boost::unit_test_framework::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_string ) );
return test;
}