diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
new file mode 100644
index 0000000..bfe0908
--- /dev/null
+++ b/doc/Jamfile.v2
@@ -0,0 +1,32 @@
+#// Boost.Range library
+#//
+#// Copyright Thorsten Ottosen 2003-2008. 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/
+#//
+
+
+use-project boost : $(BOOST_ROOT) ;
+
+
+import boostbook : boostbook ;
+import quickbook ;
+
+xml boost_range : boost_range.qbk ;
+
+boostbook standalone
+ :
+ boost_range
+ :
+
- Four types of objects are currently supported by the library:
-
- Warning: support for null-terminated strings is deprecated and will
- disappear in the next Boost release (1.34).
-
- Please also see Range concepts for more details.
-
-
+ Three types of objects are currently supported by the library:
+
+ Please also see Range concepts for more details.
+
+
-
-
-
-
-
-
-
-
- Boost.Range
- Synopsis and Reference
-
-
-
-
-
- Overview
-
-
- Even though the behavior of the primary templates are exactly such that
- standard containers will be supported by default, the requirements are much
- lower than the standard container requirements. For example, the utility class
- std::pair<iterator,iterator>
- char[]
,wchar_t[]
,
- char*
, and wchar_t*
)
- iterator_range
implements the minimal
- interface required to make the class a Forward
- Range
- .
-
- Synopsis
-
+
+
+
+
+
+
+
+
+
+ Boost.Range
+ Synopsis and Reference
+
+
+
+
+
+ Overview
+
+
+ Even though the behavior of the primary templates are exactly such that
+ standard containers will be supported by default, the requirements are much
+ lower than the standard container requirements. For example, the utility class
+ std::pair<iterator,iterator>
+ iterator_range
implements the minimal
+ interface required to make the class a Forward
+ Range
+ .
+
+ Synopsis
+
namespace boost
{
//
// Single Pass Range metafunctions
//
-
- template< class T >
- struct range_value;
-
+
template< class T >
struct range_iterator;
template< class T >
- struct range_const_iterator;
+ struct range_value;
+
+ template< class T >
+ struct range_reference;
+
+ template< class T >
+ struct range_pointer;
+ template< class T >
+ struct range_category;
+
//
// Forward Range metafunctions
//
@@ -89,10 +90,6 @@ class=identifier>range_const_iterator;
struct range_difference;
- template< class T >
- struct range_size;
-
//
// Bidirectional Range metafunctions
//
@@ -101,56 +98,38 @@ class=identifier>range_size;
struct range_reverse_iterator;
-
- template< class T >
- struct range_const_reverse_iterator;
- //
- // Special metafunctions
- //
-
- template< class T >
- struct range_result_iterator;
-
- template< class T >
- struct range_reverse_result_iterator;
-
//
// Single Pass Range functions
//
template< class T >
typename range_iterator<T>::type
- begin( T& c );
+ begin( T& r );
template< class T >
- typename range_const_iterator<T>::type
- begin( const T& c );
+ typename range_iterator<const T>::type
+ begin( const T& r );
template< class T >
typename range_iterator<T>::type
- end( T& c );
+ end( T& r );
template< class T >
- typename range_const_iterator<T>::type
- end( const T& c );
+ typename range_iterator<const T>::type
+ end( const T& r );
template< class T >
bool
- empty( const T& c );
+ empty( const T& r );
//
// Forward Range functions
//
template< class T >
- typename range_size<T>::type
- size( const T& c );
+ typename range_difference<T>::type
+ distance( const T& r );
//
// Bidirectional Range functions
@@ -158,546 +137,585 @@ class=identifier>range_reverse_result_iterator;
template< class T >
typename range_reverse_iterator<T>::type
- rbegin( T& c );
+ rbegin( T& r );
template< class T >
- typename range_const_reverse_iterator<T>::type
- rbegin( const T& c );
+ typename range_reverse_iterator<const T>::type
+ rbegin( const T& r );
template< class T >
typename range_reverse_iterator<T>::type
- rend( T& c );
+ rend( T& r );
template< class T >
- typename range_const_reverse_iterator<T>::type
+ typename range_reverse_iterator<const T>::type
rend( const T& c );
+class=identifier>T& r );
+ //
+ // Random Access Range functions
+ //
+
+ template< class T >
+ typename range_difference<T>::type
+ size( const T& r );
+
//
// Special const Range functions
//
template< class T >
- typename range_const_iterator<T>::type
+ typename range_iterator<const T>::type
const_begin( const T& r );
template< class T >
- typename range_const_iterator<T>::type
+ typename range_iterator<const T>::type
const_end( const T& r );
template< class T >
- typename range_const_reverse_iterator<T>::type
+ typename range_reverse_iterator<const T>::type
const_rbegin( const T& r );
template< class T >
- typename range_const_reverse_iterator<T>::type
+ typename range_reverse_iterator<const T>::type
const_rend( const T& r );
+ //
+ // String utilities
+ //
+
+ template< class T >
+ iterator_range<...see below...>
+ as_literal( T& r );
+
+ template< class T >
+ iterator_range<...see below...>
+ as_literal( const T& r );
+
+ template< class T >
+ iterator_range< typename range_iterator<T>::type >
+ as_array( T& r );
+
+ template< class T >
+ iterator_range< typename range_iterator<const T>::type >
+ as_array( const T& r );
+
} // namespace 'boost'
-
-
- Semantics
- notation
-
-
-
-
-
- Type
-
- Object
-
- Describes
-
- X
- x
- any type
-
-
-
- T
- t
- denotes behavior of the primary templates
-
- P
- p
- denotes
- std::pair<iterator,iterator>
- A[sz]
- a
- denotes an array of type A
of size sz
-
-
-
- Char*
- s
- denotes either
- char*
or wchar_t*
- Please notice in tables below that when four lines appear in a cell, the first - line will describe the primary template, the second line pairs of iterators, - the third line arrays and the last line null-terminated strings. -
--
- The special metafunctions range_result_iterator
and range_reverse_result_iterator
- are not part of any Range concept, but they are very useful when implementing
- certain Range classes like sub_range
- because of their ability to select iterators based on constness.
-
-
- Expression | -- Return type | -- Returns | -- Complexity | -||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
begin(x) |
- range_result_iterator<X>::type |
-
- p.first if p is of type std::pair<T> | |||||||||||||||||||
end(x) |
+ range_iterator<X>::type |
+
+ p.second if p is of type std::pair<T> | |||||||||||||||||||
empty(x) |
+ bool |
+ boost::begin(x) == boost::end(x) + | constant time + |
+ ||||||||||||||||||
distance(x) |
+ range_difference<X>::type |
+
+
+ std::distance(boost::begin(x),boost::end(x))
+
+ |
+ - | - +
- Member function | -- Related concept | -
---|---|
begin() |
- Single Pass Range | -
end()
- |
- Single Pass Range | -
size() |
- Forward Range | -
- Notice that rbegin()
and rend()
member functions are
- not needed even though the container can support bidirectional iteration.
-
- The required member types are: -
--
- Member type | -- Related concept | -
---|---|
iterator |
- Single Pass Range | -
const_iterator |
- Single Pass Range | -
size_type |
- Forward Range | -
- Again one should notice that member types reverse_iterator
and const_reverse_iterator
- are not needed.
-
size(x)
range_difference<X>::type
boost::end(x) - boost::begin(x)
+
+ rbegin(x)
range_reverse_iterator<X>::type
range_reverse_iterator<X>::type( boost::end(x) )
+ rend(x)
range_reverse_iterator<X>::type
range_reverse_iterator<X>::type( boost::begin(x) )
+ const_begin(x)
range_iterator<const X>::type
range_iterator<const X>::type( boost::begin(x) )
+ const_end(x)
range_iterator<const X>::type
range_iterator<const X>::type( boost::end(x) )
+ const_rbegin(x)
range_reverse_iterator<const X>::type
range_reverse_iterator<const X>::type( boost::rbegin(x) )
+ const_rend(x)
range_reverse_iterator<const X>::type
range_reverse_iterator<const X>::type( boost::rend(x) )
+
+ as_literal(x)
iterator_range<U>
where U
is
+ Char*
if x
is a pointer to a
+ string and U
is
+ range_iterator<X>::type
otherwise
+ [s,s + std::char_traits<X>::length(s))
if s
is a Char*
or an array of Char
+ [boost::begin(x),boost::end(x))
otherwise
- - This procedure assumes that you cannot (or do not wish to) change the types that should be made - conformant to a Range concept. If this is not true, see method 1. -
- -
- The primary templates in this library are implemented such that
- certain functions are found via argument-dependent-lookup (ADL).
- Below is given an overview of which free-standing functions a class
- must specify to be useable as a certain Range concept.
- Let x
be a variable (const
or mutable)
- of the class in question.
-
-
- Function | -- Related concept | -
---|---|
boost_range_begin(x) |
- Single Pass Range | -
boost_range_end(x)
- |
- Single Pass Range | -
boost_range_size(x) |
- Forward Range | -
boost_range_begin()
and boost_range_end()
must be
- overloaded for both const
and mutable reference arguments.
-
- You must also specialize 3 metafunctions for your type X
:
-
-
- Metafunction | -- Related concept | -
---|---|
boost::range_iterator |
- Single Pass Range | -
boost::range_const_iterator |
- Single Pass Range | -
boost::range_size |
- Forward Range | -
- A complete example is given here: -
--+ + +
Char
, constant time otherwiseas_array(x)
iterator_range<X>
[boost::begin(x),boost::end(x))
+
+
+
+
+
+ The special const_
-named functions are useful when you
+ want to document clearly that your code is read-only.
+
+ as_literal()
can be used internally in string
+ algorithm librararies such that arrays of characters are
+ handled correctly.
+
+ as_array()
can be used with string algorithm libraries to make it clear that arrays of characters are handled like an array and not like a string.
+
Notice that the above functions should always be called with
+ qualification (boost::
) to prevent unintended
+ Argument Dependent Lookup (ADL).
+
+ This procedure assumes that you have control over the types that should be made + conformant to a Range concept. If not, see method 2. +
+ +
+ The primary templates in this library are implemented such that standard
+ containers will work automatically and so will boost::array
.
+ Below is given an overview of which member functions and member types a class
+ must specify to be useable as a certain Range concept.
+
+
+ Member function | ++ Related concept | +
---|---|
begin() |
+ Single Pass Range | +
end()
+ |
+ Single Pass Range | +
+ Notice that rbegin()
and rend()
member functions are
+ not needed even though the container can support bidirectional iteration.
+
+ The required member types are: +
++
+ Member type | ++ Related concept | +
---|---|
iterator |
+ Single Pass Range | +
const_iterator |
+ Single Pass Range | +
+ Again one should notice that member types reverse_iterator
and const_reverse_iterator
+ are not needed.
+
+ This procedure assumes that you cannot (or do not wish to) change the types that should be made + conformant to a Range concept. If this is not true, see method 1. +
+ +
+ The primary templates in this library are implemented such that
+ certain functions are found via argument-dependent-lookup (ADL).
+ Below is given an overview of which free-standing functions a class
+ must specify to be useable as a certain Range concept.
+ Let x
be a variable (const
or mutable)
+ of the class in question.
+
+
+ Function | ++ Related concept | +
---|---|
range_begin(x) |
+ Single Pass Range | +
range_end(x)
+ |
+ Single Pass Range | +
range_begin()
and range_end()
must be
+ overloaded for both const
and mutable reference arguments.
+
+ You must also specialize two metafunctions for your type X
:
+
+
+ Metafunction | ++ Related concept | +
---|---|
boost::range_mutable_iterator |
+ Single Pass Range | +
boost::range_const_iterator |
+ Single Pass Range | +
+ A complete example is given here: +
++- -#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; - }; + // + // 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. - // + // + // Specialize metafunctions. We must include the range.hpp header. + // We must open the 'boost' namespace. + // - template< class T > - struct range_iterator< Foo::Pair<T> > - { - typedef T type; - }; + template< class T > + struct range_mutable_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_size< Foo::Pair<T> > - { - - typedef std::size_t type; - }; + template< class T > + struct range_const_iterator< Foo::Pair<T> > + { + // + // Remark: this is defined similar to 'range_mutable_iterator' + // because the 'Pair' type does not distinguish + // between an iterator and a const_iterator. + // + typedef 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; - } + // + // The required functions. These should be defined in + // the same namespace as 'Pair', in this case + // in namespace 'Foo'. + // + + template< class T > + inline T 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 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 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); - } + template< class T > + inline T range_end( const Pair<T>& x ) + { + return x.last; + } } // namespace 'Foo' @@ -705,41 +723,47 @@ class=identifier>T& int main() { - typedef std::vector<int>::iterator iter; - std::vector<int> vec; - 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 ); -} + typedef std::vector<int>::iterator iter; + std::vector<int> vec; + 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_difference< Foo::Pair<iter> >::type s = boost::size( pair ); + s = boost::size( cpair ); + boost::range_reverse_iterator< const Foo::Pair<iter> >::type + ri = boost::rbegin( cpair ), + re = boost::rend( cpair ); +}
- (C) Copyright Thorsten Ottosen 2003-2004 -
-+ © Copyright Thorsten Ottosen 2008. +
+ ++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt) +
+string.cpp
- std::find()
that
works with char[],wchar_t[],char*,wchar_t*.
- - Warning: support for null-terminated strings is deprecated and will - disappear in the next Boost release (1.34). -
- +algorithm_example.cpp
- - (C) Copyright Thorsten Ottosen 2003-2004 + © Copyright Thorsten Ottosen 2008. +
+ ++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)
range_iterator<C>::type
and range_const_iterator<C>::type
for std::pair<iterator, iterator>
.
-
In general it is not possible nor desirable to find a corresponding const_iterator
.
When it is possible to come up with one, the client might choose to construct a std::pair<const_iterator,const_iterator>
@@ -33,7 +33,7 @@
is somewhat more convenient than a pair
and that a sub_range
does
propagate const-ness.
@@ -114,9 +114,16 @@ Cool indeed! -
- (C) Copyright Thorsten Ottosen 2003-2004 + © Copyright Thorsten Ottosen 2008. +
+ ++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy + at www.boost.org/LICENSE_1_0.txt)
<boost/range/mutable_iterator.hpp>
<boost/range/const_iterator.hpp>
<boost/range/size_type.hpp>
<boost/range/result_iterator.hpp>
<boost/range/pointer.hpp>
<boost/range/category.hpp>
<boost/range/reverse_iterator.hpp>
<boost/range/const_reverse_iterator.hpp>
<boost/range/reverse_result_iterator.hpp>
<boost/range/begin.hpp>
<boost/range/distance.hpp>
<boost/range/size.hpp>
<boost/range/rbegin.hpp>
<boost/range/as_array.hpp>
<boost/range/as_literal.hpp>
<boost/range/iterator_range.hpp>
- (C) Copyright Thorsten Ottosen 2003-2004 + © Copyright Thorsten Ottosen 2008. +
+ ++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy + at www.boost.org/LICENSE_1_0.txt)
- The library have been under way for a long time. Dietmar Kühl originally
- intended to submit an array_traits
class template which
- had most of the functionality present now, but only for arrays and standard
- containers.
+ The library was under way for a long time. Dietmar Kühl originally intended
+ to submit an array_traits
class template which had most of
+ the functionality present now, but only for arrays and standard containers.
+ I believe this was back in 2001 or 2002.
@@ -61,7 +61,14 @@ C++ standard:
- (C) Copyright Thorsten Ottosen 2003-2006 + © Copyright Thorsten Ottosen 2008. +
+ ++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy + at www.boost.org/LICENSE_1_0.txt)
diff --git a/doc/intro.html b/doc/intro.html old mode 100755 new mode 100644 index 444b4ca..89d3504 --- a/doc/intro.html +++ b/doc/intro.html @@ -24,7 +24,7 @@ to a somewhat clumsy use of the algorithms with redundant specification of container names. Therefore we would like to raise the abstraction level for algorithms so they specify their interface in terms of Ranges as much as possible. + href="range.html">Ranges as much as possible.@@ -35,16 +35,14 @@ enough functionality to satisfy the needs of the generic code if a suitable layer of indirection is applied . 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. + works with containers, provided a suitable adapter is used.
This library therefore provides the means to adapt standard-like - containers, - null terminated strings,
std::pairs
of iterators, and raw - arrays (and more), such that the same generic code can work with them all. + containers,std::pairs
of iterators, and raw arrays (and + more), such that + the same generic code can work with them all. The basic idea is to add another layer of indirection using metafunctions and free-standing functions so syntactic and/or semantic differences can be removed. @@ -60,22 +58,13 @@ free-standing functions so syntactic and/or semantic differences can be removed. more flexible, compact and maintainable client code- correct handling of null-terminated strings - -- Warning: support for null-terminated strings is deprecated and will - disappear in the next Boost release (1.34). -
+ safe use of built-in arrays- safe use of built-in arrays (for legacy code; why else would you use - built-in arrays?) -- Below are given a small example (the complete example can be found here - ): -
+Below is given a small example (the complete example can be found here):
// @@ -89,7 +78,7 @@ free-standing functions so syntactic and/or semantic differences can be removed. } template< class ForwardReadableRange, class T > - inline typename boost::range_const_iterator< inline typename boost::range_iterator< const ForwardReadableRange >::type find( const ForwardReadableRange& c, const T& value ) { @@ -100,7 +89,7 @@ class=identifier>ForwardReadableRange >::template< class ForwardReadableWriteableRange, class T > - inline typename boost::range_size< ForwardReadableWriteableRange >::type + inline typename boost::range_difference< ForwardReadableWriteableRange >::type my_generic_replace( ForwardReadableWriteableRange& c, const T& value, const T& replacement ) { typename boost::range_iterator< ForwardReadableWriteableRange >::type found = find( c, value ); @@ -119,7 +108,7 @@ class=identifier>ForwardReadableRange >::typedef std::vector<int>::iterator iterator; + typedef std::vector<int>::iterator iterator; std::pair<iterator,iterator> my_view( boost::begin( my_vector ), boost::begin( my_vector ) + N ); char str_val[] = "a string"; @@ -146,7 +135,14 @@ Notice that we have tomy_vector.assign( values, boost::end( values ) ); -
- (C) Copyright Thorsten Ottosen 2003-2004 + © Copyright Thorsten Ottosen 2008. +
+ ++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy + at www.boost.org/LICENSE_1_0.txt)
diff --git a/doc/mfc_atl.html b/doc/mfc_atl.html new file mode 100644 index 0000000..a022fe3 --- /dev/null +++ b/doc/mfc_atl.html @@ -0,0 +1,581 @@ + + + + + + +Boost Range MFC/ATL Extension + + + + + + +++ + diff --git a/doc/mfc_atl.rst b/doc/mfc_atl.rst new file mode 100644 index 0000000..67498fb --- /dev/null +++ b/doc/mfc_atl.rst @@ -0,0 +1,232 @@ + +++++++++++++++++++++++++++++++++ + |Boost| Range MFC/ATL Extension +++++++++++++++++++++++++++++++++ + +.. |Boost| image:: http://www.boost.org/libs/ptr_container/doc/boost.png + + + +:Author: Shunsuke Sogame +:Contact: mb2act@yahoo.co.jp +:date: 26th of May 2006 +:copyright: Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt__). + +__ http://www.boost.org/LICENSE_1_0.txt + + + +======== +Overview +======== + +Boost.Range MFC/ATL Extension provides `Boost.Range`_ support for MFC/ATL collection and string types. + + +.. parsed-literal:: + + CTypedPtrArray+
Range MFC/ATL Extension
+
++ + + + Author: +Shunsuke Sogame + Contact: +mb2act@yahoo.co.jp + Date: +26th of May 2006 + + Copyright: +Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt). ++Overview
+Boost.Range MFC/ATL Extension provides Boost.Range support for MFC/ATL collection and string types.
++CTypedPtrArray<CPtrArray, CList<CString> *> myArray; +... +BOOST_FOREACH (CList<CString> *theList, myArray) +{ + BOOST_FOREACH (CString& str, *theList) + { + boost::to_upper(str); + std::sort(boost::begin(str), boost::end(str)); + ... + } +} ++ +++Requirements
++
+- Boost C++ Libraries Version 1.34.0 or later (no compilation required)
+- Visual C++ 7.1 or Visual C++ 8.0
+++MFC Ranges
+If the <boost/range/mfc.hpp> is included before or after Boost.Range headers, +the MFC collections and strings become models of Range. +The table below lists the Traversal Category and range_reference of MFC ranges.
++
++ + ++ + + + + + Range +Traversal Category +range_reference<Range>::type ++ CArray<T,A> +Random Access +T& ++ CList<T,A> +Bidirectional +T& ++ CMap<K,AK,M,AM> +Forward +Range::CPair& ++ CTypedPtrArray<B,T*> +Random Access +T* const ++ CTypedPtrList<B,T*> +Bidirectional +T* const ++ CTypedPtrMap<B,T*,V*> +Forward +std::pair<T*,V*> const ++ CByteArray +Random Access +BYTE& ++ CDWordArray +Random Access +DWORD& ++ CObArray +Random Access +CObject* & ++ CPtrArray +Random Access +void* & ++ CStringArray +Random Access +CString& ++ CUIntArray +Random Access +UINT& ++ CWordArray +Random Access +WORD& ++ CObList +Bidirectional +CObject* & ++ CPtrList +Bidirectional +void* & ++ CStringList +Bidirectional +CString& ++ CMapPtrToWord +Forward +std::pair<void*,WORD> const ++ CMapPtrToPtr +Forward +std::pair<void*,void*> const ++ CMapStringToOb +Forward +std::pair<String,CObject*> const ++ CMapStringToString +Forward +Range::CPair& ++ CMapWordToOb +Forward +std::pair<WORD,CObject*> const ++ + CMapWordToPtr +Forward +std::pair<WORD,void*> const +Other Boost.Range metafunctions are defined by the following. +Let Range be any type listed above and ReF be the same as range_reference<Range>::type. +range_value<Range>::type is the same as remove_reference<remove_const<Ref>::type>::type, +range_difference<Range>::type is the same as std::ptrdiff_t, and +range_pointer<Range>::type is the same as add_pointer<remove_reference<Ref>::type>::type. +As for const Range, see const Ranges.
+++ATL Ranges
+If the <boost/range/atl.hpp> is included before or after Boost.Range headers, +the ATL collections and strings become models of Range. +The table below lists the Traversal Category and range_reference of ATL ranges.
++
++ + ++ + + + + + Range +Traversal Category +range_reference<Range>::type ++ CAtlArray<E,ET> +Random Access +E& ++ CAutoPtrArray<E> +Random Access +E& ++ CInterfaceArray<I,pi> +Random Access +CComQIPtr<I,pi>& ++ CAtlList<E,ET> +Bidirectional +E& ++ CAutoPtrList<E> +Bidirectional +E& ++ CHeapPtrList<E,A> +Bidirectional +E& ++ CInterfaceList<I,pi> +Bidirectional +CComQIPtr<I,pi>& ++ CAtlMap<K,V,KT,VT> +Forward +Range::CPair& ++ CRBTree<K,V,KT,VT> +Bidirectional +Range::CPair& ++ CRBMap<K,V,KT,VT> +Bidirectional +Range::CPair& ++ CRBMultiMap<K,V,KT,VT> +Bidirectional +Range::CPair& ++ CSimpleStringT<B,b> +Random Access +B& ++ CStringT<B,ST> +Random Access +B& ++ CFixedStringT<S,n> +Random Access +range_reference<S>::type ++ CStringT<B,ST> +Random Access +B& ++ CComBSTR +Random Access +OLECHAR& ++ + CSimpleArray<T,TE> +Random Access +T& +Other Boost.Range metafunctions are defined by the following. +Let Range be any type listed above and ReF be the same as range_reference<Range>::type. +range_value<Range>::type is the same as remove_reference<Ref>::type, +range_difference<Range>::type is the same as std::ptrdiff_t, and +range_pointer<Range>::type is the same as add_pointer<remove_reference<Ref>::type>::type. +As for const Range, see const Ranges.
+++ +const Ranges
+range_reference<const Range>::type is defined by the following algorithm. +Let Range be any type listed above and ReF be the same as range_reference<Range>::type.
++if (Range is CObArray || Range is CObList) + return CObject const * & +else if (Range is CPtrArray || Range is CPtrList) + return void const * & +else if (there is a type X such that X& is the same as ReF) + return X const & +else if (there is a type X such that X* const is the same as ReF) + return X const * const +else + return ReF ++Other Boost.Range metafunctions are defined by the following. +range_value<const Range>::type is the same as range_value<Range>::type, +range_difference<const Range>::type is the same as std::ptrdiff_t, and +range_pointer<const Range>::type is the same as add_pointer<remove_reference<range_reference<const Range>::type>::type>::type.
+\*> myArray; + ... + BOOST_FOREACH (CList \*theList, myArray) + { + BOOST_FOREACH (CString& str, \*theList) + { + boost::to_upper(str); + std::sort(boost::begin(str), boost::end(str)); + ... + } + } + + + +* `Requirements`_ +* `MFC Ranges`_ +* `ATL Ranges`_ +* `const Ranges`_ +* `References`_ + + + +============ +Requirements +============ + +- `Boost C++ Libraries Version 1.34.0`__ or later (no compilation required) +- Visual C++ 7.1 or Visual C++ 8.0 + +__ Boost_ + + + +========== +MFC Ranges +========== + +If the `` `` is included before or after `Boost.Range`_ headers, +the MFC collections and strings become models of Range. +The table below lists the Traversal Category and ``range_reference`` of MFC ranges. + + +============================= ================== ======================================= +``Range`` Traversal Category ``range_reference ::type`` +============================= ================== ======================================= +``CArray `` Random Access ``T&`` +----------------------------- ------------------ --------------------------------------- +``CList `` Bidirectional ``T&`` +----------------------------- ------------------ --------------------------------------- +``CMap `` Forward ``Range::CPair&`` +----------------------------- ------------------ --------------------------------------- +``CTypedPtrArray`` Random Access ``T* const`` +----------------------------- ------------------ --------------------------------------- +``CTypedPtrList`` Bidirectional ``T* const`` +----------------------------- ------------------ --------------------------------------- +``CTypedPtrMap`` Forward ``std::pair const`` +----------------------------- ------------------ --------------------------------------- +``CByteArray`` Random Access ``BYTE&`` +----------------------------- ------------------ --------------------------------------- +``CDWordArray`` Random Access ``DWORD&`` +----------------------------- ------------------ --------------------------------------- +``CObArray`` Random Access ``CObject* &`` +----------------------------- ------------------ --------------------------------------- +``CPtrArray`` Random Access ``void* &`` +----------------------------- ------------------ --------------------------------------- +``CStringArray`` Random Access ``CString&`` +----------------------------- ------------------ --------------------------------------- +``CUIntArray`` Random Access ``UINT&`` +----------------------------- ------------------ --------------------------------------- +``CWordArray`` Random Access ``WORD&`` +----------------------------- ------------------ --------------------------------------- +``CObList`` Bidirectional ``CObject* &`` +----------------------------- ------------------ --------------------------------------- +``CPtrList`` Bidirectional ``void* &`` +----------------------------- ------------------ --------------------------------------- +``CStringList`` Bidirectional ``CString&`` +----------------------------- ------------------ --------------------------------------- +``CMapPtrToWord`` Forward ``std::pair const`` +----------------------------- ------------------ --------------------------------------- +``CMapPtrToPtr`` Forward ``std::pair const`` +----------------------------- ------------------ --------------------------------------- +``CMapStringToOb`` Forward ``std::pair const`` +----------------------------- ------------------ --------------------------------------- +``CMapStringToString`` Forward ``Range::CPair&`` +----------------------------- ------------------ --------------------------------------- +``CMapWordToOb`` Forward ``std::pair const`` +----------------------------- ------------------ --------------------------------------- +``CMapWordToPtr`` Forward ``std::pair const`` +============================= ================== ======================================= + + +Other `Boost.Range`_ metafunctions are defined by the following. +Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference ::type``. +``range_value ::type`` is the same as ``remove_reference ::type>::type``, +``range_difference ::type`` is the same as ``std::ptrdiff_t``, and +``range_pointer ::type`` is the same as ``add_pointer ::type>::type``. +As for ``const Range``, see `const Ranges`_. + + + +========== +ATL Ranges +========== + +If the `` `` is included before or after `Boost.Range`_ headers, +the ATL collections and strings become models of Range. +The table below lists the Traversal Category and ``range_reference`` of ATL ranges. + + +============================= ================== ======================================= +``Range`` Traversal Category ``range_reference ::type`` +============================= ================== ======================================= +``CAtlArray `` Random Access ``E&`` +----------------------------- ------------------ --------------------------------------- +``CAutoPtrArray `` Random Access ``E&`` +----------------------------- ------------------ --------------------------------------- +``CInterfaceArray`` Random Access ``CComQIPtr&`` +----------------------------- ------------------ --------------------------------------- +``CAtlList `` Bidirectional ``E&`` +----------------------------- ------------------ --------------------------------------- +``CAutoPtrList `` Bidirectional ``E&`` +----------------------------- ------------------ --------------------------------------- +``CHeapPtrList `` Bidirectional ``E&`` +----------------------------- ------------------ --------------------------------------- +``CInterfaceList`` Bidirectional ``CComQIPtr&`` +----------------------------- ------------------ --------------------------------------- +``CAtlMap `` Forward ``Range::CPair&`` +----------------------------- ------------------ --------------------------------------- +``CRBTree `` Bidirectional ``Range::CPair&`` +----------------------------- ------------------ --------------------------------------- +``CRBMap `` Bidirectional ``Range::CPair&`` +----------------------------- ------------------ --------------------------------------- +``CRBMultiMap `` Bidirectional ``Range::CPair&`` +----------------------------- ------------------ --------------------------------------- +``CSimpleStringT`` Random Access ``B&`` +----------------------------- ------------------ --------------------------------------- +``CStringT`` Random Access ``B&`` +----------------------------- ------------------ --------------------------------------- +``CFixedStringT `` Random Access ``range_reference::type`` +----------------------------- ------------------ --------------------------------------- +``CStringT`` Random Access ``B&`` +----------------------------- ------------------ --------------------------------------- +``CComBSTR`` Random Access ``OLECHAR&`` +----------------------------- ------------------ --------------------------------------- +``CSimpleArray`` Random Access ``T&`` +============================= ================== ======================================= + + +Other `Boost.Range`_ metafunctions are defined by the following. +Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference ::type``. +``range_value ::type`` is the same as ``remove_reference::type``, +``range_difference ::type`` is the same as ``std::ptrdiff_t``, and +``range_pointer ::type`` is the same as ``add_pointer ::type>::type``. +As for ``const Range``, see `const Ranges`_. + + + +============ +const Ranges +============ + +``range_reference ::type`` is defined by the following algorithm. +Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference ::type``. + + +.. parsed-literal:: + + if (Range is CObArray || Range is CObList) + return CObject const \* & + else if (Range is CPtrArray || Range is CPtrList) + return void const \* & + else if (there is a type X such that X& is the same as ReF) + return X const & + else if (there is a type X such that X* const is the same as ReF) + return X const \* const + else + return ReF + + +Other `Boost.Range`_ metafunctions are defined by the following. +``range_value ::type`` is the same as ``range_value ::type``, +``range_difference ::type`` is the same as ``std::ptrdiff_t``, and +``range_pointer ::type`` is the same as ``add_pointer ::type>::type>::type``. + + + +========== +References +========== +- `Boost.Range`_ +- `MFC Collections`__ +- `ATL Collection Classes`__ + +__ http://msdn2.microsoft.com/en-us/library/942860sh.aspx +__ http://msdn2.microsoft.com/en-US/library/15e672bd.aspx + + + +.. _Boost C++ Libraries: http://www.boost.org/ +.. _Boost: `Boost C++ Libraries`_ +.. _Boost.Range: ../index.html +.. _forward: range.html#forward_range +.. _bidirectional: range.html#forward_range +.. _random access: range.html#random_access_range + diff --git a/doc/portability.html b/doc/portability.html old mode 100755 new mode 100644 index ae3a264..bb73e78 --- a/doc/portability.html +++ b/doc/portability.html @@ -29,14 +29,13 @@ href="http://boost.sourceforge.net/regression-logs/developer/range.html">here - - Visual C++ 6/7.0 has a limited support for arrays: as long as the arrays are - of built-in type it should work. + Visual C++ 6/7.0 has a limited support for arrays: as long as the arrays + are of built-in type it should work.
Notice also that some compilers cannot do function template ordering properly. - In that case one must rely of
-range_result_iterator
+ In that case one must rely onrange_iterator
and a single function definition instead of overloaded versions for const and non-const arguments. @@ -73,11 +72,18 @@ href="http://boost.sourceforge.net/regression-logs/developer/range.html">here
+
- (C) Copyright Thorsten Ottosen 2003-2004 + © Copyright Thorsten Ottosen 2008.
++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy + at www.boost.org/LICENSE_1_0.txt) +
> +
diff --git a/doc/range.html b/doc/range.html old mode 100755 new mode 100644 index 03a773d..8646141 --- a/doc/range.html +++ b/doc/range.html @@ -1,3 +1,4 @@ +
- +Single Pass Range
Notation
@@ -118,11 +119,7 @@ Single Pass IteratorAssociated types
-
- +Value type -- boost::range_value<X>::type
The type of the object stored in a Range. - Iterator type @@ -132,7 +129,7 @@ Single Pass Iterator boost::range_iterator<X>::type
@@ -161,20 +158,16 @@ Single Pass Iterator Const iterator type -+ boost::range_const_iterator<X>::type
boost::range_iterator<const X>::type
A type of iterator that may be used to examine, but not to modify, a Range's elements. Beginning of range boost::begin(a)
boost::range_iterator<X>::type
if -a
is mutable,boost::range_const_iterator<X>::type
+a
is mutable,boost::range_iterator<const X>::type
otherwise- End of range boost::end(a)
boost::range_iterator<X>::type
if -a
is mutable,boost::range_const_iterator<X>::type
+a
is mutable,boost::range_iterator<const X>::type
otherwise- +Is range empty? -- boost::empty(a)
Convertible to -bool
Expression semantics
@@ -188,7 +181,7 @@ otherwise
boost::begin(a)
boost::begin(a)
is either dereferenceable or past-the-end.
- It is past-the-end if and only if boost::size(a) == 0
.boost::distance(a) == 0
.
boost::end(a)
boost::end(a)
is past-the-end.boost::empty(a)
boost::begin(a) == boost::end(a)
. (But possibly
- faster.)boost::begin(a)
, boost::end(a)
and boost::empty(a)
- to be amortized constant time.
+ boost::end(a)
is at most amortized linear time, boost::begin(a)
is
+ amortized constant time. For most practical
+ purposes, one can expect both to be amortized constant time.
Distance type | -boost::range_difference<X>::type |
- A signed integral type used to represent the distance between - two of the Range's iterators. This type must be the same as the iterator's - distance type. | -
Size type | -boost::range_size<X>::type |
- An unsigned integral type that can represent any nonnegative - value of the Range's distance type. | -
Name | -Expression | -Return type | -
---|---|---|
Size of range | -boost::size(a) |
- boost::range_size<X>::type |
-
Expression | -Semantics | -Postcondition | -
---|---|---|
boost::size(a) |
- Returns the size of the Range, that is, its number
-of elements. Note boost::size(a) == 0u is equivalent to
-boost::empty(a). |
- boost::size(a) >= 0 |
-
boost::size(a)
is at most amortized linear time.
-
Range size | -boost::size(a) is equal to the distance from boost::begin(a)
- to boost::end(a) . |
implementation of - metafunctions
- - - + +Reverse Iterator type | -boost::range_reverse_iterator<X>::type |
- The type of iterator used to iterate through a Range's elements - in reverse order. The iterator's value type is expected to be the Range's value - type. A conversion from the reverse iterator type to the const reverse iterator - type must exist. | -
Const reverse iterator type | -boost::range_const_reverse_iterator<X>::type |
- A type of reverse iterator that may be used to examine, but not - to modify, a Range's elements. | -
Name | -Expression | -Return type | -Semantics | -
---|---|---|---|
Beginning of range | -boost::rbegin(a) |
- boost::range_reverse_iterator<X>::type if
-a is mutable, boost::range_const_reverse_iterator<X>::type
-otherwise. |
- Equivalent to
-boost::range_reverse_iterator<X>::type(boost::end(a)) . |
End of range | -boost::rend(a) |
- boost::range_reverse_iterator<X>::type if
-a is mutable, boost::range_const_reverse_iterator<X>::type
-otherwise. |
- Equivalent to
-boost::range_reverse_iterator<X>::type(boost::begin(a)) . |
boost::rbegin(a)
has the same complexity as boost::end(a)
and boost::rend(a)
- has the same complexity as boost::begin(a)
from Forward Range.
-
- -
Valid reverse range | -For any Bidirectional Range a , [boost::rbegin(a),boost::rend(a))
- is a valid range, that is, boost::rend(a) is reachable from boost::rbegin(a)
- in a finite number of increments. |
-
Completeness | -An algorithm that iterates through the range [boost::rbegin(a),boost::rend(a))
- will pass through every element of a . |
-
implementation of metafunctions
- - + +
A range X
where boost::range_iterator<X>::type
is a model
of Boost Concept
Check library to insure that the type of a template parameter
@@ -505,34 +354,16 @@ href="../../iterator/doc/new-iter-concepts.html#random-access-traversal-iterator
+ © Copyright Thorsten Ottosen 2008. +
- - -Copyright © 2000 | -Jeremy Siek - |
Copyright © 2004 | -Thorsten Ottosen. - |
+ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy + at www.boost.org/LICENSE_1_0.txt) +
@@ -104,9 +104,15 @@
- (C) Copyright Thorsten Ottosen 2003-2004 + © Copyright Thorsten Ottosen 2008.
++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy + at www.boost.org/LICENSE_1_0.txt) +
![]() |
+ Boost.Range |
+
+ Boost v. 1.35 introduced some larger refactorings of the library: +
+range_size<T>::type
has been completely removed
+ in favor of range_difference<T>::type
+ boost_range_begin()
and boost_range_end()
+ have been renamed range_begin()
and range_begin()
, respectively.range_result_iterator<T>::type
and
+ range_reverse_result_iterator<T>::type
are have
+ been renamed
+ range_iterator<T>::type
and
+ range_reverse_iterator<T>::type
.
+ + © Copyright Thorsten Ottosen 2008. +
+ ++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt) +
+ +iterator_range
+ Class iterator_range
sub_range
- sub_range
- The iterator_range
class is templated on an
- Forward
+ The iterator_range
class is templated on a Forward
Traversal Iterator and should be used whenever fairly general code is needed.
- The sub_range
class is templated on an Forward
- Range and it is less general, but a bit easier to use since its template
+ The sub_range
class is templated on a Forward Range and it is less general,
+ but a bit easier to use since its template
argument is easier to specify. The biggest difference is, however, that a
sub_range
can propagate constness because it knows what a
corresponding const_iterator
is.
@@ -59,19 +59,16 @@ corresponding const_iterator
is.
If the template argument is not a model of Forward Traversal Iterator, one can
still use a subset of the interface. In particular, size()
requires
- Forward Traversal Iterators whereas empty()
only requires Single
+ Random Access Iterators whereas empty()
only requires Single
Pass Iterators.
Recall that many default constructed iterators
are singular and hence can only be assigned, but not compared or
- incremented or anything. However, if one creates a default constructed
- iterator_range
, then one
- can still call all its member functions. This means that the
- iterator_range
will still be usable in many contexts even
- though the iterators underneath are not.
-
iterator_range
, then one have to be careful about not doing
+ anything besides copying.
const_iterator
is.
class iterator_range
{
public: // Forward Range types
- typedef ... value_type;
- typedef ... difference_type;
- typedef ... size_type;
- typedef ForwardTraversalIterator iterator;
- typedef ForwardTraversalIterator const_iterator;
-
- public: // construction, assignment
+ typedef ForwardTraversalIterator iterator;
+ typedef ForwardTraversalIterator const_iterator;
+ typedef iterator_difference<iterator>::type difference_type;
+
+ public: // construction, assignment
template< class ForwardTraversalIterator2 >
iterator_range( ForwardTraversalIterator2 Begin, ForwardTraversalIterator2 End );
@@ -105,23 +100,25 @@ corresponding const_iterator
is.
iterator_range& operator=( const ForwardRange& r );
public: // Forward Range functions
- iterator begin() const;
- iterator end() const;
- size_type size() const;
- bool empty() const;
+ iterator begin() const;
+ iterator end() const;
+ difference_type size() const;
+ bool empty() const;
public: // convenience
- operator unspecified_bool_type() const;
- bool operator unspecified_bool_type() const;
+ bool equal( const iterator_range& ) ( const iterator_range& ) const;
- value_type& front() const;
- value_type& back() const;
+ reference front() const;
+ reference back() const;
+ iterator_range& advance_begin( difference_type n );
+ iterator_range& advance_end( difference_type n );
// for Random Access Range only:
- value_type& operator[]( size_type at ) const;
- };
+ reference operator[]( difference_type at ) const;
+ value_type operator()( difference_type at ) const;
+ };
// stream output
template< class ForwardTraversalIterator, class T, class Traits >
@@ -166,18 +163,18 @@ class=keyword>const;
bool operator<( const ForwardRange& l,
const iterator_range<ForwardTraversalIterator>& r );
- // external construction
+ // external construction
template< class ForwardTraversalIterator >
iterator_range< ForwardTraversalIterator >
make_iterator_range( ForwardTraversalIterator Begin,
ForwardTraversalIterator End );
template< class ForwardRange >
- iterator_range< typename iterator_of<ForwardRange>::type >
+ iterator_range< typename range_iterator<ForwardRange>::type >
make_iterator_range( ForwardRange& r );
template< class ForwardRange >
- iterator_range< typename const_iterator_of<ForwardRange>::type >
+ iterator_range< typename range_iterator<const ForwardRange>::type >
make_iterator_range( const ForwardRange& r );
template< class Range >
@@ -187,12 +184,12 @@ class=keyword>const;
typename range_difference<Range>::type advance_end );
template< class Range >
- iterator_range< typename range_const_iterator<Range>::type >
+ iterator_range< typename range_iterator<const Range>::type >
make_iterator_range( const Range& r,
typename range_difference<Range>::type advance_begin,
typename range_difference<Range>::type advance_end );
- // convenience
+ // convenience
template< class Sequence, class ForwardRange >
Sequence copy_range(
-bool equal( iterator_range& r ) const;
+bool equal( iterator_range& r ) const;
- Returns@@ -238,21 +235,21 @@ non-const iterators from the same container.begin() == r.begin() && end() == r.end();
+ Returnsbegin() == r.begin() && end() == r.end();
-bool operator==( const ForwardRange1& l, const ForwardRange2& r );
+bool operator==( const ForwardRange1& l, const ForwardRange2& r );
Returns size(l) != size(r) ? false : std::equal( begin(l), end(l), begin(r) );
-bool operator!=( const ForwardRange1& l, const ForwardRange2& r );
+bool operator!=( const ForwardRange1& l, const ForwardRange2& r );
Returns !( l == r );
-bool operator<( const ForwardRange1& l, const ForwardRange2& r );
+bool operator<( const ForwardRange1& l, const ForwardRange2& r );
Returns std::lexicographical_compare( begin(l), end(l), begin(r), end(r) );
-iterator_range make_iterator_range( Range& r, +iterator_range make_iterator_range( Range& r, typename range_difference<Range>::type advance_begin, typename range_difference<Range>::type advance_end );@@ -268,7 +265,7 @@ return make_iterator_range( new_begin, new_end );
-Sequence copy_range( const ForwardRange& r );
+Sequence copy_range( const ForwardRange& r );
Returns Sequence( begin(r), end(r) );
@@ -291,12 +288,14 @@ class can propagate constness since it knows what a corresponding
namespace boost
{
template< class ForwardRange >
- class sub_range : public iterator_range< typename range_result_iterator<ForwardRange>::type >
+ class sub_range : public iterator_range< typename range_iterator<ForwardRange>::type >
{
public:
- typedef typename range_result_iterator<ForwardRangeiterator_range
+ // rest of interface inherited from iterator_range
};
} // namespace 'boost'
@@ -344,16 +343,23 @@ store the result
from this algorithm. Here is an example of how we can do it with and without
sub_range
- std::string str("hello"); - iterator_range<std::string::iterator> ir = find_first( str, "ll" ); - sub_range<std::string> sub = find_first( str, "ll" ); + std::string str("hello"); + iterator_range<std::string::iterator> ir = find_first( str, as_literal("ll") ); + sub_range<std::string> sub = find_first( str, as_literal("ll") );-
- (C) Copyright Thorsten Ottosen 2003-2004 -
++ © Copyright Thorsten Ottosen 2008. +
+ ++ Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy + at www.boost.org/LICENSE_1_0.txt) +