Compare commits

...

9 Commits

Author SHA1 Message Date
nobody
40920f5879 This commit was manufactured by cvs2svn to create tag
'Version_1_33_1_beta'.

[SVN r31604]
2005-11-08 23:18:41 +00:00
Thorsten Jørgen Ottosen
99378979c2 *** empty log message ***
[SVN r31520]
2005-10-31 23:11:00 +00:00
John Maddock
848c11831e Re-enable broken compiler workarounds (they cause regressions if not present).
[SVN r31512]
2005-10-31 13:29:56 +00:00
Thorsten Jørgen Ottosen
823d513129 *** empty log message ***
[SVN r30988]
2005-09-14 17:05:05 +00:00
Thorsten Jørgen Ottosen
21c1285cd0 *** empty log message ***
[SVN r30927]
2005-09-12 20:08:14 +00:00
Thorsten Jørgen Ottosen
a47b8664f7 simplified metafunctions interface
[SVN r30889]
2005-09-09 16:11:29 +00:00
Thorsten Jørgen Ottosen
19d2d83d29 added remove_const to parameters to avoid common instantiations errors
[SVN r30855]
2005-09-07 16:13:23 +00:00
Thorsten Jørgen Ottosen
06e624858b added discussion on extension mechanism
[SVN r30854]
2005-09-07 16:12:03 +00:00
Thorsten Jørgen Ottosen
43a83f500e added test for extension mechanism
[SVN r30815]
2005-09-05 19:44:09 +00:00
12 changed files with 955 additions and 416 deletions

File diff suppressed because it is too large Load Diff

141
doc/example.cpp Normal file
View File

@@ -0,0 +1,141 @@
#include <boost/range.hpp>
#include <iterator> // for std::iterator_traits, std::distance()
namespace Foo
{
//
// Our sample UDT. A 'Pair'
// will work as a range when the stored
// elements are iterators.
//
template< class T >
struct Pair
{
T first, last;
};
} // namespace 'Foo'
namespace boost
{
//
// Specialize metafunctions. We must include the range.hpp header.
// We must open the 'boost' namespace.
//
/*
template< class T >
struct range_value< Foo::Pair<T> >
{
typedef typename std::iterator_traits<T>::value_type type;
};
*/
template< class T >
struct range_iterator< Foo::Pair<T> >
{
typedef T type;
};
template< class T >
struct range_const_iterator< Foo::Pair<T> >
{
//
// Remark: this is defined similar to 'range_iterator'
// because the 'Pair' type does not distinguish
// between an iterator and a const_iterator.
//
typedef T type;
};
/*
template< class T >
struct range_difference< Foo::Pair<T> >
{
typedef typename std::iterator_traits<T>::difference_type type;
};
*/
template< class T >
struct range_size< Foo::Pair<T> >
{
int static_assertion[ sizeof( std::size_t ) >=
sizeof( typename range_difference< Foo::Pair<T> >::type ) ];
typedef std::size_t type;
};
} // namespace 'boost'
namespace Foo
{
//
// The required functions. These should be defined in
// the same namespace as 'Pair', in this case
// in namespace 'Foo'.
//
template< class T >
inline T boost_range_begin( Pair<T>& x )
{
return x.first;
}
template< class T >
inline T boost_range_begin( const Pair<T>& x )
{
return x.first;
}
template< class T >
inline T boost_range_end( Pair<T>& x )
{
return x.last;
}
template< class T >
inline T boost_range_end( const Pair<T>& x )
{
return x.last;
}
template< class T >
inline typename boost::range_size< Pair<T> >::type
boost_range_size( const Pair<T>& x )
{
return std::distance(x.first,x.last);
}
} // namespace 'Foo'
#include <vector>
int main()
{
typedef std::vector<int>::iterator iter;
std::vector<int> vec;
vec.push_back( 42 );
Foo::Pair<iter> pair = { vec.begin(), vec.end() };
const Foo::Pair<iter>& cpair = pair;
//
// Notice that we call 'begin' etc with qualification.
//
iter i = boost::begin( pair );
iter e = boost::end( pair );
i = boost::begin( cpair );
e = boost::end( cpair );
boost::range_size< Foo::Pair<iter> >::type s = boost::size( pair );
s = boost::size( cpair );
boost::range_const_reverse_iterator< Foo::Pair<iter> >::type
ri = boost::rbegin( cpair ),
re = boost::rend( cpair );
//
// Test metafunctions
//
boost::range_value< Foo::Pair<iter> >::type
v = *boost::begin(pair);
boost::range_difference< Foo::Pair<iter> >::type
d = boost::end(pair) - boost::begin(pair);
}

View File

@@ -386,7 +386,7 @@ VAlign="top"><code>boost::range_const_reverse_iterator&ltX>::type</code></TD>
</TR>
<TR>
<TD VAlign="top">Beginning of range</TD>
<TD VAlign="top"><code>rboost::begin(a)</code></TD>
<TD VAlign="top"><code>boost::rbegin(a)</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD>
@@ -394,7 +394,7 @@ otherwise.</TD>
<code>boost::range_reverse_iterator&lt;X>::type(boost::end(a))</code>.</TD> </TR>
<TR>
<TD VAlign="top">End of range</TD>
<TD VAlign="top"><code>rboost::end(a)</code></TD>
<TD VAlign="top"><code>boost::rend(a)</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD>
@@ -405,7 +405,7 @@ otherwise.</TD>
<h3>Complexity guarantees</h3>
<code>rboost::begin(a)</code> has the same complexity as <code>boost::end(a)</code> and <code>rboost::end(a)</code>
<code>boost::rbegin(a)</code> has the same complexity as <code>boost::end(a)</code> and <code>boost::rend(a)</code>
has the same complexity as <code>boost::begin(a)</code> from <a
href="#forward_range">Forward Range</a>.
@@ -414,13 +414,13 @@ otherwise.</TD>
<Table border="1" cellpadding="5">
<TR>
<TD VAlign="top">Valid reverse range</TD>
<TD VAlign="top">For any Bidirectional Range <code>a</code>, <code>[rboost::begin(a),rboost::end(a))</code>
is a valid range, that is, <code>rboost::end(a)</code> is reachable from <code>rboost::begin(a)</code>
<TD VAlign="top">For any Bidirectional Range <code>a</code>, <code>[boost::rbegin(a),boost::rend(a))</code>
is a valid range, that is, <code>boost::rend(a)</code> is reachable from <code>boost::rbegin(a)</code>
in a finite number of increments.</TD>
</TR>
<TR>
<TD VAlign="top">Completeness</TD>
<TD VAlign="top">An algorithm that iterates through the range <code>[rboost::begin(a),rboost::end(a))</code>
<TD VAlign="top">An algorithm that iterates through the range <code>[boost::rbegin(a),boost::rend(a))</code>
will pass through every element of <code>a</code>.</TD>
</tr>
</table>

View File

@@ -15,6 +15,7 @@
# pragma once
#endif
#include <boost/type_traits/remove_const.hpp>
#include <boost/range/config.hpp>
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
@@ -46,7 +47,8 @@ namespace range_detail
}
template< typename C >
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<C>::type >::type
boost_range_begin( C& c )
{
return c.begin();
@@ -140,7 +142,8 @@ namespace range_detail
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<T>::type >::type begin( T& r )
{
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \

View File

@@ -16,12 +16,25 @@
#endif
#include <boost/range/config.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/difference_type.hpp>
#else
#include <boost/range/const_iterator.hpp>
#include <boost/iterator/iterator_traits.hpp>
namespace boost
{
template< class T >
struct range_difference
{
typedef BOOST_DEDUCED_TYPENAME iterator_difference<
BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type >::type
type;
};
}
//#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//#include <boost/range/detail/difference_type.hpp>
//#else
/*
#include <cstddef>
#include <utility>
@@ -127,5 +140,6 @@ namespace boost
} // namespace boost
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
*/
#endif

View File

@@ -15,6 +15,7 @@
# pragma once
#endif
#include <boost/type_traits/remove_const.hpp>
#include <boost/range/config.hpp>
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
@@ -47,7 +48,8 @@ namespace range_detail
}
template< typename C >
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<C>::type >::type
boost_range_end( C& c )
{
return c.end();
@@ -139,7 +141,8 @@ namespace range_detail
#endif
template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<T>::type >::type end( T& r )
{
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \

View File

@@ -35,10 +35,12 @@ rbegin( C& c )
#else
template< class C >
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
rbegin( C& c )
{
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
iter_type;
return iter_type( end( c ) );
}

View File

@@ -35,10 +35,12 @@ rend( C& c )
#else
template< class C >
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
rend( C& c )
{
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
iter_type;
return iter_type( begin( c ) );
}

View File

@@ -16,6 +16,54 @@
#endif
#include <boost/range/config.hpp>
/*
#include <boost/range/difference_type.hpp>
namespace boost
{
namespace range_detail
{
template< class T >
struct add_unsigned;
template<>
struct add_unsigned<short>
{
typedef unsigned short type;
};
template<>
struct add_unsigned<int>
{
typedef unsigned int type;
};
template<>
struct add_unsigned<long>
{
typedef unsigned long type;
};
#ifdef BOOST_HAS_LONG_LONG
template<>
struct add_unsigned<long long>
{
typedef unsigned long long type;
};
#endif
}
template< class T >
struct range_size
{
typedef BOOST_DEDUCED_TYPENAME range_detail::add_unsigned<
BOOST_DEDUCED_TYPENAME range_difference<T>::type >::type
type;
};
}
*/
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/size_type.hpp>
@@ -124,4 +172,5 @@ namespace boost
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif

View File

@@ -16,12 +16,26 @@
#endif
#include <boost/range/config.hpp>
#include <boost/range/iterator.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/value_type.hpp>
#else
#include <boost/iterator/iterator_traits.hpp>
namespace boost
{
template< class T >
struct range_value
{
typedef BOOST_DEDUCED_TYPENAME iterator_value<
BOOST_DEDUCED_TYPENAME range_iterator<T>::type >::type
type;
};
}
/*
#include <cstddef>
#include <utility>
@@ -126,7 +140,7 @@ namespace boost
};
} // namespace boost
*/
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif

View File

@@ -35,6 +35,7 @@ test-suite range :
[ range-test algorithm_example ]
[ range-test reversible_range ]
[ range-test const_ranges ]
[ range-test extension_mechanism ]
# [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
;

112
test/extension_mechanism.cpp Executable file
View File

@@ -0,0 +1,112 @@
// 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/detail/workaround.hpp>
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# pragma warn -8091 // supress warning in Boost.Test
# pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif
#include <boost/range.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
//
// Generic range algorithm
//
template< class Rng >
typename boost::range_result_iterator<Rng>::type foo_algo( Rng& r )
{
//
// This will only compile for Rng = UDT if the qualified calls
// find boost_range_XXX via ADL.
//
return boost::size(r) == 0u ? boost::begin(r) : boost::end(r);
}
namespace Foo
{
//
// Our sample UDT
//
struct X
{
typedef std::vector<int> data_t;
typedef data_t::iterator iterator;
typedef data_t::const_iterator const_iterator;
typedef data_t::size_type size_type;
data_t vec;
void push_back( int i )
{ vec.push_back(i); }
};
//
// The required functions. No type-traits need
// to be defined because X defines the proper set of
// nested types.
//
inline X::iterator boost_range_begin( X& x )
{
return x.vec.begin();
}
inline X::const_iterator boost_range_begin( const X& x )
{
return x.vec.begin();
}
inline X::iterator boost_range_end( X& x )
{
return x.vec.end();
}
inline X::const_iterator boost_range_end( const X& x )
{
return x.vec.end();
}
inline X::size_type boost_range_size( const X& x )
{
return x.vec.size();
}
}
void check_extension()
{
Foo::X x;
x.push_back(3);
const Foo::X x2;
foo_algo( x );
foo_algo( x2 );
}
using boost::unit_test::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_extension ) );
return test;
}