forked from boostorg/range
Compare commits
1 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
4300becb58 |
@ -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 §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< 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::const_iterator_of<EC>::type found = find( c, value );
|
||||
*found = replacement;
|
||||
return std::distance( boost::begin( c ), found );
|
||||
}
|
||||
|
||||
//
|
||||
// usage
|
||||
//
|
||||
std::vector<int> my_vector;
|
||||
typedef vector<int>::iterator iterator;
|
||||
std::pair<iterator,iterator> my_view( my_vector.begin(), my_vector.begin() + 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' );
|
||||
</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 <boost/collection_traits.hpp></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<iterator,iterator></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 ><boost/collection_traits.hpp></code></td><td >everything</td></tr><tr ><td ><code ><boost/collection_traits/types.hpp></code></td><td >every type-generator</td></tr><tr ><td ><code ><boost/collection_traits/functions.hpp></code></td><td >every function</td></tr><tr ><td ><code ><boost/collection_traits/value_type.hpp></code></td><td ><a href="#value_type_of" >value_type_of</a></td></tr><tr ><td ><code ><boost/collection_traits/iterator.hpp></code></td><td ><a href="#iterator_of" >iterator_of</a></td></tr><tr ><td ><code ><boost/collection_traits/const_iterator.hpp></code></td><td ><a href="#const_iterator_of" >const_iterator_of</a></td></tr><tr ><td ><code ><boost/collection_traits/difference_type.hpp></code></td><td ><a href="#difference_type_of" >difference_type_of</a></td></tr><tr ><td ><code ><boost/collection_traits/size_type.hpp></code></td><td ><a href="#size_type_of" >size_type_of</a></td></tr><tr ><td ><code ><boost/collection_traits/result_iterator.hpp></code></td><td ><a href="#result_iterator_of" >result_iterator_of</a></td></tr><tr ><td ><code ><boost/collection_traits/begin.hpp></code></td><td ><a href="#begin" >begin</a></td></tr><tr ><td ><code ><boost/collection_traits/end.hpp></code></td><td ><a href="#end" >end</a></td></tr><tr ><td ><code ><boost/collection_traits/empty.hpp></code></td><td ><a href="#empty" >empty</a></td></tr><tr ><td ><code ><boost/collection_traits/size.hpp></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<></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<C>::type</code></td><td ><code >SC::value_type</code><br><code >T</code><br><code >std::iterator_traits<P::first_type>::value_type</code><br><code >std::iterator_traits<I>::value_type</code></td><td >compile time</td></tr><tr ><a name="iterator_of" ></a><td ><code >iterator_of<C>::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<C>::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<C>::type</code></td><td ><code >SC::difference_type</code><br><code >std::ptrdiff_t</code><br><code >std::iterator_traits<P::first_type>::difference_type</code><br><code >std::iterator_traits<I>::difference_type</code></td><td >compile time</td></tr><tr ><a name="size_type_of" ></a><td ><code >size_type_of<C>::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<C>::type</code></td><td ><code >const_iterator_of<C>::type</code> if <code >C</code> is <code >const</code><br><code >iterator_of<C>::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<C>::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<C>::type</code></td><td ><code >sc.end()</code><br><code >t + std::char_traits<C>::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<C>::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<>.</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<></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<></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<C>::type</code> and <code >const_iterator_of<C>::type</code> for <code >std::pair<iterator,iterator></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<const_iterator,const_iterator></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<></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 >© 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 -->
|
BIN
doc/cboost.gif
BIN
doc/cboost.gif
Binary file not shown.
Before Width: | Height: | Size: 8.6 KiB |
@ -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 >© 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 -->
|
612
doc/range.htm
612
doc/range.htm
@ -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 "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/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() >= 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/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 © 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 © 2004</TD><TD>
|
||||
Thorsten Ottosen.
|
||||
</TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
@ -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>
|
||||
|
||||
|
||||
|
59
test/Jamfile
59
test/Jamfile
@ -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
|
||||
] ;
|
||||
}
|
86
test/TODO
86
test/TODO
@ -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.
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
152
test/string.cpp
152
test/string.cpp
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user