Boost logo

Boost-Commit :

From: nesotto_at_[hidden]
Date: 2007-10-23 16:28:53


Author: nesotto
Date: 2007-10-23 16:28:52 EDT (Tue, 23 Oct 2007)
New Revision: 40381
URL: http://svn.boost.org/trac/boost/changeset/40381

Log:
Shunsuke Sogame's MFC/ATL docs and tests
Added:
   trunk/libs/range/doc/mfc_atl.html (contents, props changed)
   trunk/libs/range/doc/mfc_atl.rst (contents, props changed)
   trunk/libs/range/test/atl.cpp (contents, props changed)
Text files modified:
   trunk/libs/range/test/mfc.cpp | 769 +++++++++++++++++++++++++++++++++++++--
   1 files changed, 714 insertions(+), 55 deletions(-)

Added: trunk/libs/range/doc/mfc_atl.html
==============================================================================
--- (empty file)
+++ trunk/libs/range/doc/mfc_atl.html 2007-10-23 16:28:52 EDT (Tue, 23 Oct 2007)
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>Boost Range MFC/ATL Extension</title>
+<meta name="author" content="Shunsuke Sogame" />
+<meta name="date" content="26th of May 2006" />
+<meta name="copyright" content="Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt)." />
+<style type="text/css">
+
+@import "http://www.boost.org/libs/ptr_container/doc/default.css";
+
+</style>
+</head>
+<body>
+<div class="document" id="boost-range-mfc-atl-extension">
+<h1 class="title"><img alt="Boost" src="http://www.boost.org/libs/ptr_container/doc/boost.png" /> Range MFC/ATL Extension</h1>
+<table class="docinfo" frame="void" rules="none">
+<col class="docinfo-name" />
+<col class="docinfo-content" />
+<tbody valign="top">
+<tr><th class="docinfo-name">Author:</th>
+<td>Shunsuke Sogame</td></tr>
+<tr><th class="docinfo-name">Contact:</th>
+<td><a class="first last reference" href="mailto:mb2act&#64;yahoo.co.jp">mb2act&#64;yahoo.co.jp</a></td></tr>
+<tr><th class="docinfo-name">Date:</th>
+<td>26th of May 2006</td></tr>
+<tr><th class="docinfo-name">Copyright:</th>
+<td>Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">LICENSE_1_0.txt</a>).</td></tr>
+</tbody>
+</table>
+<div class="section">
+<h1><a id="overview" name="overview">Overview</a></h1>
+<p>Boost.Range MFC/ATL Extension provides <a class="reference" href="http://www.boost.org/libs/range/">Boost.Range</a> support for MFC/ATL collection and string types.</p>
+<pre class="literal-block">
+CTypedPtrArray&lt;CPtrArray, CList&lt;CString&gt; *&gt; myArray;
+...
+BOOST_FOREACH (CList&lt;CString&gt; *theList, myArray)
+{
+ BOOST_FOREACH (CString&amp; str, *theList)
+ {
+ boost::to_upper(str);
+ std::sort(boost::begin(str), boost::end(str));
+ ...
+ }
+}
+</pre>
+<ul class="simple">
+<li><a class="reference" href="#requirements">Requirements</a></li>
+<li><a class="reference" href="#mfc-ranges">MFC Ranges</a></li>
+<li><a class="reference" href="#atl-ranges">ATL Ranges</a></li>
+<li><a class="reference" href="#const-ranges">const Ranges</a></li>
+<li><a class="reference" href="#references">References</a></li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="requirements" name="requirements">Requirements</a></h1>
+<ul class="simple">
+<li><a class="reference" href="http://www.boost.org/">Boost C++ Libraries Version 1.34.0</a> or later (no compilation required)</li>
+<li>Visual C++ 7.1 or Visual C++ 8.0</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="mfc-ranges" name="mfc-ranges">MFC Ranges</a></h1>
+<p>If the <tt class="docutils literal"><span class="pre">&lt;boost/range/mfc.hpp&gt;</span></tt> is included before or after <a class="reference" href="http://www.boost.org/libs/range/">Boost.Range</a> headers,
+the MFC collections and strings become models of Range.
+The table below lists the Traversal Category and <tt class="docutils literal"><span class="pre">range_reference</span></tt> of MFC ranges.</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="34%" />
+<col width="21%" />
+<col width="45%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head"><tt class="docutils literal"><span class="pre">Range</span></tt></th>
+<th class="head">Traversal Category</th>
+<th class="head"><tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt></th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td><tt class="docutils literal"><span class="pre">CArray&lt;T,A&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">T&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CList&lt;T,A&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">T&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CMap&lt;K,AK,M,AM&gt;</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CTypedPtrArray&lt;B,T*&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">T*</span> <span class="pre">const</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CTypedPtrList&lt;B,T*&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">T*</span> <span class="pre">const</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CTypedPtrMap&lt;B,T*,V*&gt;</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">std::pair&lt;T*,V*&gt;</span> <span class="pre">const</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CByteArray</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">BYTE&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CDWordArray</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">DWORD&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CObArray</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">CObject*</span> <span class="pre">&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CPtrArray</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">void*</span> <span class="pre">&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CStringArray</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">CString&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CUIntArray</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">UINT&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CWordArray</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">WORD&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CObList</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">CObject*</span> <span class="pre">&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CPtrList</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">void*</span> <span class="pre">&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CStringList</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">CString&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CMapPtrToWord</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">std::pair&lt;void*,WORD&gt;</span> <span class="pre">const</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CMapPtrToPtr</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">std::pair&lt;void*,void*&gt;</span> <span class="pre">const</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CMapStringToOb</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">std::pair&lt;String,CObject*&gt;</span> <span class="pre">const</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CMapStringToString</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CMapWordToOb</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">std::pair&lt;WORD,CObject*&gt;</span> <span class="pre">const</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CMapWordToPtr</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">std::pair&lt;WORD,void*&gt;</span> <span class="pre">const</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Other <a class="reference" href="http://www.boost.org/libs/range/">Boost.Range</a> metafunctions are defined by the following.
+Let <tt class="docutils literal"><span class="pre">Range</span></tt> be any type listed above and <tt class="docutils literal"><span class="pre">ReF</span></tt> be the same as <tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt>.
+<tt class="docutils literal"><span class="pre">range_value&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">remove_reference&lt;remove_const&lt;Ref&gt;::type&gt;::type</span></tt>,
+<tt class="docutils literal"><span class="pre">range_difference&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">std::ptrdiff_t</span></tt>, and
+<tt class="docutils literal"><span class="pre">range_pointer&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">add_pointer&lt;remove_reference&lt;Ref&gt;::type&gt;::type</span></tt>.
+As for <tt class="docutils literal"><span class="pre">const</span> <span class="pre">Range</span></tt>, see <a class="reference" href="#const-ranges">const Ranges</a>.</p>
+</div>
+<div class="section">
+<h1><a id="atl-ranges" name="atl-ranges">ATL Ranges</a></h1>
+<p>If the <tt class="docutils literal"><span class="pre">&lt;boost/range/atl.hpp&gt;</span></tt> is included before or after <a class="reference" href="http://www.boost.org/libs/range/">Boost.Range</a> headers,
+the ATL collections and strings become models of Range.
+The table below lists the Traversal Category and <tt class="docutils literal"><span class="pre">range_reference</span></tt> of ATL ranges.</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="34%" />
+<col width="21%" />
+<col width="45%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head"><tt class="docutils literal"><span class="pre">Range</span></tt></th>
+<th class="head">Traversal Category</th>
+<th class="head"><tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt></th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td><tt class="docutils literal"><span class="pre">CAtlArray&lt;E,ET&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CAutoPtrArray&lt;E&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CInterfaceArray&lt;I,pi&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">CComQIPtr&lt;I,pi&gt;&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CAtlList&lt;E,ET&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CAutoPtrList&lt;E&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CHeapPtrList&lt;E,A&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CInterfaceList&lt;I,pi&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">CComQIPtr&lt;I,pi&gt;&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CAtlMap&lt;K,V,KT,VT&gt;</span></tt></td>
+<td>Forward</td>
+<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CRBTree&lt;K,V,KT,VT&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CRBMap&lt;K,V,KT,VT&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CRBMultiMap&lt;K,V,KT,VT&gt;</span></tt></td>
+<td>Bidirectional</td>
+<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CSimpleStringT&lt;B,b&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">B&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CStringT&lt;B,ST&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">B&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CFixedStringT&lt;S,n&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">range_reference&lt;S&gt;::type</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CStringT&lt;B,ST&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">B&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CComBSTR</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">OLECHAR&amp;</span></tt></td>
+</tr>
+<tr><td><tt class="docutils literal"><span class="pre">CSimpleArray&lt;T,TE&gt;</span></tt></td>
+<td>Random Access</td>
+<td><tt class="docutils literal"><span class="pre">T&amp;</span></tt></td>
+</tr>
+</tbody>
+</table>
+<p>Other <a class="reference" href="http://www.boost.org/libs/range/">Boost.Range</a> metafunctions are defined by the following.
+Let <tt class="docutils literal"><span class="pre">Range</span></tt> be any type listed above and <tt class="docutils literal"><span class="pre">ReF</span></tt> be the same as <tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt>.
+<tt class="docutils literal"><span class="pre">range_value&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">remove_reference&lt;Ref&gt;::type</span></tt>,
+<tt class="docutils literal"><span class="pre">range_difference&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">std::ptrdiff_t</span></tt>, and
+<tt class="docutils literal"><span class="pre">range_pointer&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">add_pointer&lt;remove_reference&lt;Ref&gt;::type&gt;::type</span></tt>.
+As for <tt class="docutils literal"><span class="pre">const</span> <span class="pre">Range</span></tt>, see <a class="reference" href="#const-ranges">const Ranges</a>.</p>
+</div>
+<div class="section">
+<h1><a id="const-ranges" name="const-ranges">const Ranges</a></h1>
+<p><tt class="docutils literal"><span class="pre">range_reference&lt;const</span> <span class="pre">Range&gt;::type</span></tt> is defined by the following algorithm.
+Let <tt class="docutils literal"><span class="pre">Range</span></tt> be any type listed above and <tt class="docutils literal"><span class="pre">ReF</span></tt> be the same as <tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt>.</p>
+<pre class="literal-block">
+if (Range is CObArray || Range is CObList)
+ return CObject const * &amp;
+else if (Range is CPtrArray || Range is CPtrList)
+ return void const * &amp;
+else if (there is a type X such that X&amp; is the same as ReF)
+ return X const &amp;
+else if (there is a type X such that X* const is the same as ReF)
+ return X const * const
+else
+ return ReF
+</pre>
+<p>Other <a class="reference" href="http://www.boost.org/libs/range/">Boost.Range</a> metafunctions are defined by the following.
+<tt class="docutils literal"><span class="pre">range_value&lt;const</span> <span class="pre">Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">range_value&lt;Range&gt;::type</span></tt>,
+<tt class="docutils literal"><span class="pre">range_difference&lt;const</span> <span class="pre">Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">std::ptrdiff_t</span></tt>, and
+<tt class="docutils literal"><span class="pre">range_pointer&lt;const</span> <span class="pre">Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">add_pointer&lt;remove_reference&lt;range_reference&lt;const</span> <span class="pre">Range&gt;::type&gt;::type&gt;::type</span></tt>.</p>
+</div>
+<div class="section">
+<h1><a id="references" name="references">References</a></h1>
+<ul class="simple">
+<li><a class="reference" href="http://www.boost.org/libs/range/">Boost.Range</a></li>
+<li><a class="reference" href="http://msdn2.microsoft.com/en-us/library/942860sh.aspx">MFC Collections</a></li>
+<li><a class="reference" href="http://msdn2.microsoft.com/en-US/library/15e672bd.aspx">ATL Collection Classes</a></li>
+</ul>
+</div>
+</div>
+<div class="footer">
+<hr class="footer" />
+<a class="reference" href="mfc_atl.rst">View document source</a>.
+Generated on: 2006-06-04 22:37 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+
+</div>
+</body>
+</html>

Added: trunk/libs/range/doc/mfc_atl.rst
==============================================================================
--- (empty file)
+++ trunk/libs/range/doc/mfc_atl.rst 2007-10-23 16:28:52 EDT (Tue, 23 Oct 2007)
@@ -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_at_[hidden]
+: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<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`_
+* `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 ``<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``.
+
+
+.. 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<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``.
+
+
+
+==========
+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: http://www.boost.org/libs/range/
+.. _forward: http://www.boost.org/libs/range/doc/range.html#forward_range
+.. _bidirectional: http://www.boost.org/libs/range/doc/range.html#forward_range
+.. _random access: http://www.boost.org/libs/range/doc/range.html#random_access_range
+

Added: trunk/libs/range/test/atl.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/range/test/atl.cpp 2007-10-23 16:28:52 EDT (Tue, 23 Oct 2007)
@@ -0,0 +1,623 @@
+
+
+// Boost.Range ATL Extension
+//
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under 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)
+
+
+// #include <pstade/vodka/drink.hpp>
+
+#include <boost/test/test_tools.hpp>
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+
+#define BOOST_LIB_NAME boost_test_exec_monitor
+#include <boost/config/auto_link.hpp>
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_TEST
+#include <boost/range/atl.hpp> // can be placed first
+
+
+#include <map>
+#include <string>
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+#include <boost/foreach.hpp>
+
+
+#include <atlbase.h> // for ATL3 CSimpleArray/CSimpleValArray
+#if !(_ATL_VER < 0x0700)
+ #include <atlcoll.h>
+ #include <cstringt.h>
+ #include <atlsimpstr.h>
+ #include <atlstr.h>
+#endif
+
+
+namespace brdm = boost::range_detail_microsoft;
+
+
+#if !(_ATL_VER < 0x0700)
+
+
+template< class ArrayT, class SampleRange >
+bool test_init_auto_ptr_array(ArrayT& arr, SampleRange& sample)
+{
+ typedef typename boost::range_iterator<SampleRange>::type iter_t;
+
+ for (iter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+ arr.Add(*it); // moves ownership
+ }
+
+ return boost::distance(arr) == boost::distance(sample);
+}
+
+
+template< class ListT, class SampleRange >
+bool test_init_auto_ptr_list(ListT& lst, SampleRange& sample)
+{
+ typedef typename boost::range_iterator<SampleRange>::type iter_t;
+ typedef typename boost::range_value<SampleRange>::type val_t;
+
+ for (iter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+ lst.AddTail(*it); // moves ownership
+ }
+
+ return boost::distance(lst) == boost::distance(sample);
+}
+
+
+// Workaround:
+// CRBTree provides no easy access function, but yes, it is the range!
+//
+template< class AtlMapT, class KeyT, class MappedT >
+bool test_atl_map_has(AtlMapT& map, const KeyT& k, const MappedT m)
+{
+ typedef typename boost::range_iterator<AtlMapT>::type iter_t;
+
+ for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
+ if (it->m_key == k && it->m_value == m)
+ return true;
+ }
+
+ return false;
+}
+
+
+template< class AtlMapT, class MapT >
+bool test_atl_map(AtlMapT& map, const MapT& sample)
+{
+ typedef typename boost::range_iterator<AtlMapT>::type iter_t;
+ typedef typename boost::range_const_iterator<MapT>::type siter_t;
+
+ bool result = true;
+
+ result = result && (boost::distance(map) == boost::distance(sample));
+ if (!result)
+ return false;
+
+ {
+ for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
+ result = result && brdm::test_find_key_and_mapped(sample, std::make_pair(it->m_key, it->m_value));
+ }
+ }
+
+ {
+ for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+ result = result && (test_atl_map_has)(map, it->first, it->second);
+ }
+ }
+
+ return result;
+}
+
+
+template< class MapT, class SampleMap >
+bool test_init_atl_multimap(MapT& map, const SampleMap& sample)
+{
+ typedef typename boost::range_const_iterator<SampleMap>::type iter_t;
+
+ for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
+ map.Insert(it->first, it->second);
+ }
+
+ return boost::distance(map) == boost::distance(sample);
+}
+
+
+// arrays
+//
+
+template< class Range >
+void test_CAtlArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ATL::CAtlArray<val_t> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class ValT, class Range >
+void test_CAutoPtrArray(Range& sample)
+{
+ typedef ValT val_t;
+
+ typedef ATL::CAutoPtrArray<val_t> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, boost::indirect_iterator< ATL::CAutoPtr<val_t> *> >::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, boost::indirect_iterator< ATL::CAutoPtr<val_t> const*> >::value ));
+
+ rng_t rng;
+ BOOST_CHECK( ::test_init_auto_ptr_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class I, class Range >
+void test_CInterfaceArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ATL::CInterfaceArray<I> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, ATL::CComQIPtr<I> * >::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, ATL::CComQIPtr<I> const* >::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// lists
+//
+
+template< class Range >
+void test_CAtlList(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ATL::CAtlList<val_t> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, val_t> >::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const> >::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_list(rng, sample) );
+ BOOST_CHECK( brdm::test_bidirectional(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class ValT, class Range >
+void test_CAutoPtrList(Range& sample)
+{
+ typedef ValT val_t;
+
+ typedef ATL::CAutoPtrList<val_t> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t, ATL::CAutoPtr<val_t> > > >::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t const, ATL::CAutoPtr<val_t> const> > >::value ));
+
+ rng_t rng;
+ BOOST_CHECK( ::test_init_auto_ptr_list(rng, sample) );
+ BOOST_CHECK( brdm::test_bidirectional(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class ValT, class Range >
+void test_CHeapPtrList(const Range& sample)
+{
+ typedef ValT val_t;
+
+ typedef ATL::CHeapPtrList<val_t> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t, ATL::CHeapPtr<val_t> > > >::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t const, ATL::CHeapPtr<val_t> const> > >::value ));
+
+ rng_t rng;
+ BOOST_CHECK( ::test_init_auto_ptr_list(rng, sample) );
+ BOOST_CHECK( brdm::test_bidirectional(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class I, class Range >
+void test_CInterfaceList(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ATL::CInterfaceList<I> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ATL::CComQIPtr<I> > >::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ATL::CComQIPtr<I> const> >::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_list(rng, sample) );
+ BOOST_CHECK( brdm::test_bidirectional(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// strings
+//
+
+template< class Range >
+void test_CSimpleStringT(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
+ ATL::CAtlStringA,
+ ATL::CAtlStringW
+ >::type derived_t;
+
+ typedef ATL::CSimpleStringT<val_t> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value ));
+
+ derived_t drng;
+ rng_t& rng = drng;
+ BOOST_CHECK( brdm::test_init_string(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ // BOOST_CHECK( brdm::test_emptiness(rng) ); no default constructible
+}
+
+
+template< int n, class Range >
+void test_CFixedStringT(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
+ ATL::CAtlStringA,
+ ATL::CAtlStringW
+ >::type base_t;
+
+ typedef ATL::CFixedStringT<base_t, n> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_string(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CStringT(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
+ ATL::CAtlStringA, // == CStringT<char, X>
+ ATL::CAtlStringW // == CStringT<wchar_t, X>
+ >::type rng_t;
+
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_string(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CStaticString(const Range& sample)
+{
+#if !defined(BOOST_RANGE_ATL_NO_TEST_UNDOCUMENTED_RANGE)
+ {
+ typedef ATL::CStaticString<char, 20> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, char const *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, char const *>::value ));
+
+ rng_t rng("hello static string");
+ BOOST_CHECK( *(boost::begin(rng)+4) == 'o' );
+ BOOST_CHECK( *(boost::end(rng)-3) == 'i' );
+ }
+
+ {
+ typedef ATL::CStaticString<wchar_t, 40> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, wchar_t const *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, wchar_t const *>::value ));
+
+ rng_t rng(L"hello static string");
+ BOOST_CHECK( *(boost::begin(rng)+4) == L'o' );
+ BOOST_CHECK( *(boost::end(rng)-3) == L'i' );
+ }
+#endif
+
+ (void)sample; // unused
+}
+
+
+#endif // !(_ATL_VER < 0x0700)
+
+
+template< class Range >
+void test_CComBSTR(const Range& sample)
+{
+ typedef ATL::CComBSTR rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, OLECHAR *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, OLECHAR const*>::value ));
+
+ rng_t rng(OLESTR("hello CComBSTR range!"));
+ BOOST_CHECK( brdm::test_equals(rng, std::string("hello CComBSTR range!")) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+
+ (void)sample; // unused
+}
+
+
+// simples
+//
+
+template< class Range >
+void test_CSimpleArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ATL::CSimpleArray<val_t> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CSimpleMap(const Range& sample)
+{
+#if !defined(BOOST_RANGE_ATL_NO_TEST_UNDOCUMENTED_RANGE)
+
+ typedef ATL::CSimpleMap<int, double> rng_t;
+
+ rng_t rng;
+ rng.Add(3, 3.0);
+ rng.Add(4, 2.0);
+
+ BOOST_CHECK( boost::begin(rng)->get<0>() == 3.0 );
+ BOOST_CHECK( (boost::end(rng)-1)->get<1>() == 2.0 );
+
+#endif
+
+ (void)sample; // unused
+}
+
+
+template< class Range >
+void test_CSimpleValArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ATL::CSimpleArray<val_t> rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// maps
+//
+
+template< class MapT >
+void test_CAtlMap(const MapT& sample)
+{
+ typedef typename MapT::key_type k_t;
+ typedef typename MapT::mapped_type m_t;
+
+ typedef ATL::CAtlMap<k_t, m_t> rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+ BOOST_CHECK( ::test_atl_map(rng, sample) );
+}
+
+
+template< class MapT >
+void test_CRBTree(const MapT& sample)
+{
+ typedef typename MapT::key_type k_t;
+ typedef typename MapT::mapped_type m_t;
+
+ typedef ATL::CRBMap<k_t, m_t> derived_t;
+ typedef ATL::CRBTree<k_t, m_t> rng_t;
+
+ derived_t drng;
+ rng_t& rng = drng;
+
+ boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(drng, sample) );
+ BOOST_CHECK( ::test_atl_map(rng, sample) );
+}
+
+
+template< class MapT >
+void test_CRBMap(const MapT& sample)
+{
+ typedef typename MapT::key_type k_t;
+ typedef typename MapT::mapped_type m_t;
+
+ typedef ATL::CRBMap<k_t, m_t> rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+ BOOST_CHECK( ::test_atl_map(rng, sample) );
+}
+
+
+template< class MapT >
+void test_CRBMultiMap(const MapT& sample)
+{
+ typedef typename MapT::key_type k_t;
+ typedef typename MapT::mapped_type m_t;
+
+ typedef ATL::CRBMultiMap<k_t, m_t> rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
+ BOOST_CHECK( ::test_init_atl_multimap(rng, sample) );
+ BOOST_CHECK( ::test_atl_map(rng, sample) );
+}
+
+
+// main test
+//
+
+void test_atl()
+{
+
+ // ordinary ranges
+ //
+ {
+ std::string sample("rebecca judy and mary whiteberry chat monchy");
+#if !(_ATL_VER < 0x0700)
+ ::test_CAtlArray(sample);
+ ::test_CAtlList(sample);
+ ::test_CSimpleStringT(sample);
+ ::test_CFixedStringT<44>(sample);
+ ::test_CStringT(sample);
+ ::test_CStaticString(sample);
+#endif
+ ::test_CComBSTR(sample);
+ ::test_CSimpleArray(sample);
+ ::test_CSimpleMap(sample);
+ ::test_CSimpleValArray(sample);
+ }
+
+
+ {
+ std::wstring sample(L"rebecca judy and mary whiteberry chat monchy");
+#if !(_ATL_VER < 0x0700)
+ ::test_CAtlArray(sample);
+ ::test_CAtlList(sample);
+ ::test_CSimpleStringT(sample);
+ ::test_CFixedStringT<44>(sample);
+ ::test_CStringT(sample);
+ ::test_CStaticString(sample);
+#endif
+ ::test_CComBSTR(sample);
+ ::test_CSimpleArray(sample);
+ ::test_CSimpleMap(sample);
+ ::test_CSimpleValArray(sample);
+ }
+
+ // pointer ranges
+ //
+#if !(_ATL_VER < 0x0700)
+ {
+ typedef ATL::CAutoPtr<int> ptr_t;
+ ptr_t
+ ptr0(new int(3)), ptr1(new int(4)), ptr2(new int(5)), ptr3(new int(4)),
+ ptr4(new int(1)), ptr5(new int(2)), ptr6(new int(4)), ptr7(new int(0));
+
+ ptr_t ptrs[8] = {
+ ptr0, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7
+ };
+
+ boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
+ ::test_CAutoPtrArray<int>(workaround);
+ }
+
+ {
+ typedef ATL::CAutoPtr<int> ptr_t;
+ ptr_t
+ ptr0(new int(3)), ptr1(new int(4)), ptr2(new int(5)), ptr3(new int(4)),
+ ptr4(new int(1)), ptr5(new int(2)), ptr6(new int(4)), ptr7(new int(0));
+
+ ptr_t ptrs[8] = {
+ ptr0, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7
+ };
+
+ boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
+ ::test_CAutoPtrList<int>(workaround);
+ }
+
+ {
+ typedef ATL::CHeapPtr<int> ptr_t;
+ ptr_t ptrs[5]; {
+ ptrs[0].AllocateBytes(sizeof(int));
+ ptrs[1].AllocateBytes(sizeof(int));
+ ptrs[2].AllocateBytes(sizeof(int));
+ ptrs[3].AllocateBytes(sizeof(int));
+ ptrs[4].AllocateBytes(sizeof(int));
+ }
+
+ boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+5);
+ ::test_CHeapPtrList<int>(workaround);
+ }
+
+
+ {
+ typedef ATL::CComQIPtr<IDispatch> ptr_t;
+ ptr_t ptrs[8];
+
+ boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
+ ::test_CInterfaceArray<IDispatch>(workaround);
+ ::test_CInterfaceList<IDispatch>(workaround);
+ }
+#endif
+
+ // maps
+ //
+ {
+#if !(_ATL_VER < 0x0700)
+ std::map<int, std::string> sample; {
+ sample[0] = "hello";
+ sample[1] = "range";
+ sample[2] = "atl";
+ sample[3] = "mfc";
+ sample[4] = "collections";
+ }
+
+ ::test_CAtlMap(sample);
+ ::test_CRBTree(sample);
+ ::test_CRBMap(sample);
+ ::test_CRBMultiMap(sample);
+#endif
+ }
+
+
+} // test_atl
+
+
+#include <boost/test/unit_test.hpp>
+using boost::unit_test::test_suite;
+
+
+test_suite *
+init_unit_test_suite(int argc, char* argv[])
+{
+ test_suite *test = BOOST_TEST_SUITE("ATL Range Test Suite");
+ test->add(BOOST_TEST_CASE(&test_atl));
+
+ (void)argc, (void)argv; // unused
+ return test;
+}

Modified: trunk/libs/range/test/mfc.cpp
==============================================================================
--- trunk/libs/range/test/mfc.cpp (original)
+++ trunk/libs/range/test/mfc.cpp 2007-10-23 16:28:52 EDT (Tue, 23 Oct 2007)
@@ -1,86 +1,745 @@
-// Boost.Range library
+
+
+// Boost.Range MFC Extension
 //
-// 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)
+// Copyright Shunsuke Sogame 2005-2006.
+// Distributed under 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)
+
+
+#include <afx.h> // must be here
+
+// #include <pstade/vodka/drink.hpp>
+
+#include <boost/test/test_tools.hpp>
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+
+#define BOOST_LIB_NAME boost_test_exec_monitor
+#include <boost/config/auto_link.hpp>
+
+#define BOOST_RANGE_DETAIL_MICROSOFT_TEST
+#include <boost/range/mfc.hpp> // can be placed first
+
+
+#include <map>
+#include <boost/concept_check.hpp>
+// #include <boost/foreach.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/end.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/algorithm/string.hpp>
+
+
+#include <afx.h>
+#include <afxcoll.h>
+#include <afxtempl.h>
+
+#if !(_ATL_VER < 0x0700)
+ #include <cstringt.h>
+ #include <atlsimpstr.h>
+ #include <atlstr.h>
+#endif
+
+
+namespace brdm = boost::range_detail_microsoft;
+
+
+// helpers
 //
-// For more information, see http://www.boost.org/libs/range/
+
+template< class MfcMapT, class MapT >
+bool test_mfc_map(MfcMapT& map, const MapT& sample)
+{
+ typedef typename boost::range_iterator<MfcMapT>::type iter_t;
+ typedef typename boost::range_const_iterator<MapT>::type siter_t;
+
+ bool result = true;
+
+ result = result && (boost::distance(map) == boost::distance(sample));
+ if (!result)
+ return false;
+
+ {
+ for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
+ result = result && brdm::test_find_key_and_mapped(sample, *it);
+ }
+ }
+
+ {
+ for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+ result = result && (map[it->first] == it->second);
+ }
+ }
+
+ return result;
+}
+
+
+template< class MfcMapT, class MapT >
+bool test_mfc_cpair_map(MfcMapT& map, const MapT& sample)
+{
+ typedef typename boost::range_iterator<MfcMapT>::type iter_t;
+ typedef typename boost::range_const_iterator<MapT>::type siter_t;
+
+ bool result = true;
+
+ result = result && (boost::distance(map) == boost::distance(sample));
+ if (!result)
+ return false;
+
+ {
+ for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
+ result = result && brdm::test_find_key_and_mapped(sample, std::make_pair(it->key, it->value));
+ }
+ }
+
+ {
+ for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
+ result = result && (map[it->first] == it->second);
+ }
+ }
+
+ return result;
+}
+
+
+// arrays
 //
+template< class Range >
+void test_CByteArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CByteArray rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, BYTE *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, BYTE const*>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CDWordArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CDWordArray rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, DWORD *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, DWORD const*>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CObArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
 
-#define _MSL_USING_NAMESPACE 1
+ typedef ::CObArray rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, brdm::mfc_ptr_array_iterator<rng_t, ::CObject *> >::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, brdm::mfc_ptr_array_iterator<const rng_t, const ::CObject *> >::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CPtrArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CPtrArray rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, brdm::mfc_ptr_array_iterator<rng_t, void *> >::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, brdm::mfc_ptr_array_iterator<const rng_t, const void *> >::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
 
-#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
+template< class Range >
+void test_CStringArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CStringArray rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, ::CString *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, ::CString const *>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CUIntArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CUIntArray rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, UINT *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, UINT const *>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CWordArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CWordArray rng_t;
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, WORD *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, WORD const *>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// lists
+//
+
+template< class Range >
+void test_CObList(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CObList rng_t;
+
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ::CObject *> >::value ));
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CObject const *> >::value ));
+#else
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CObject const * const, ::CObject const * const> >::value ));
 #endif
 
-#define BOOST_RANGE_ENABLE_MFC
-#define BOOST_RANGE_ENABLE_MCF_CARRAY
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_list(rng, sample) );
+ BOOST_CHECK( brdm::test_bidirectional(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
 
-/*
-#define WIN32
-#define _WINDOWS
-#define _MBCS
-#define _AFXDLL
-#define _ATL_DLL
-*/
 
-///Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_MBCS" /D "_AFXDLL" /D "_ATL_DLL" /Gm /EHsc /RTC1
-// /MDd /Zc:wchar_t /Yu"stdafx.h" /Fp"Debug/Foo.pch" /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Wp64 /ZI /TP
+template< class Range >
+void test_CPtrList(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
 
-#include <boost/range.hpp>
-#include <boost/range/detail/mfc/carray.hpp>
-#include <boost/range/detail/mfc/cstring.hpp>
+ typedef ::CPtrList rng_t;
 
-#include <boost/test/test_tools.hpp>
-#include <boost/config.hpp>
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, void *> >::value ));
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, void const *> >::value ));
+#else
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, void const * const, void const * const> >::value ));
+#endif
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_list(rng, sample) );
+ BOOST_CHECK( brdm::test_bidirectional(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
 
 
-void check_mfc()
+template< class Range >
+void test_CStringList(const Range& sample)
 {
- CString s = "hello world";
- BOOST_CHECK( boost::begin( s ) + boost::size( s ) == boost::end( s ) );
- BOOST_CHECK( boost::size( s ) == boost::size( "hello world" ) );
- BOOST_CHECK( !boost::empty( s ) );
- const CString cs( s );
- BOOST_CHECK( boost::begin( cs ) + boost::size( cs ) == boost::end( cs ) );
- BOOST_CHECK( boost::size( cs ) == boost::size( "hello world" ) );
- BOOST_CHECK( !boost::empty( cs ) );
-
- CArray<int,int> a;
- BOOST_CHECK( boost::empty( a ) );
- a.Add( 5 );
- a.Add( 10 );
- BOOST_CHECK( boost::begin( a ) + boost::size( a ) == boost::end( a ) );
- BOOST_CHECK( boost::size( a ) == 2 );
- BOOST_CHECK( !boost::empty( a ) );
- const CArray<int,int>& ca = a;
- BOOST_CHECK( boost::begin( ca ) + boost::size( ca ) == boost::end( ca ) );
- BOOST_CHECK( boost::size( ca ) == 2 );
- BOOST_CHECK( !boost::empty( ca ) );
-
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CStringList rng_t;
+
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ::CString> >::value ));
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CString const> >::value ));
+#else
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CString const, ::CString const> >::value ));
+#endif
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_list(rng, sample) );
+ BOOST_CHECK( brdm::test_bidirectional(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
 }
 
 
+// maps
+//
 
-#include <boost/test/unit_test.hpp>
-using boost::unit_test::test_suite;
+template< class MapT >
+void test_CMapPtrToWord(const MapT& sample)
+{
+ typedef ::CMapPtrToWord rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+ BOOST_CHECK( ::test_mfc_map(rng, sample) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
 
 
-test_suite* init_unit_test_suite( int argc, char* argv[] )
+template< class MapT >
+void test_CMapPtrToPtr(const MapT& sample)
 {
- test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
+ typedef ::CMapPtrToPtr rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+ BOOST_CHECK( ::test_mfc_map(rng, sample) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
 
- test->add( BOOST_TEST_CASE( &check_mfc ) );
 
- return test;
+template< class MapT >
+void test_CMapStringToOb(const MapT& sample)
+{
+ typedef ::CMapStringToOb rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+ BOOST_CHECK( ::test_mfc_map(rng, sample) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
 }
 
 
+template< class MapT >
+void test_CMapStringToPtr(const MapT& sample)
+{
+ typedef ::CMapStringToPtr rng_t;
 
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+ BOOST_CHECK( ::test_mfc_map(rng, sample) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
 
 
+template< class MapT >
+void test_CMapStringToString(const MapT& sample)
+{
+ typedef ::CMapStringToString rng_t;
 
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+ BOOST_CHECK( ::test_mfc_cpair_map(rng, sample) );
+#endif
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMapWordToOb(const MapT& sample)
+{
+ typedef ::CMapWordToOb rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+ BOOST_CHECK( ::test_mfc_map(rng, sample) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMapWordToPtr(const MapT& sample)
+{
+ typedef ::CMapWordToPtr rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+ BOOST_CHECK( ::test_mfc_map(rng, sample) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// templates
+//
+
+template< class Range >
+void test_CArray(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CArray<val_t, const val_t&> rng_t; // An old MFC needs the second template argument.
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_array(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class Range >
+void test_CList(const Range& sample)
+{
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CList<val_t, const val_t&> rng_t;
+
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, val_t> >::value ));
+#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const> >::value ));
+#else
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const, val_t const> >::value ));
+#endif
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_list(rng, sample) );
+ BOOST_CHECK( brdm::test_bidirectional(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+template< class MapT >
+void test_CMap(const MapT& sample)
+{
+ typedef typename MapT::key_type k_t;
+ typedef typename MapT::mapped_type m_t;
+
+ typedef ::CMap<k_t, const k_t&, m_t, const m_t&> rng_t;
+
+ rng_t rng;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+ BOOST_CHECK( brdm::test_init_map(rng, sample) );
+#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
+ BOOST_CHECK( ::test_mfc_cpair_map(rng, sample) );
+#endif
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+void test_CTypedPtrArray()
+{
+ typedef ::CTypedPtrArray< ::CPtrArray, int * > rng_t;
+ boost::function_requires< boost::RandomAccessRangeConcept<rng_t> >();
+
+ rng_t rng;
+ int o1, o2, o3, o4, o5;
+ int *data[] = { &o1, &o2, &o3, &o4, &o5 };
+ BOOST_CHECK( brdm::test_init_array(rng, boost::make_iterator_range(data, data+5)) );
+
+ BOOST_CHECK( *(boost::begin(rng) + 2) == &o3 );
+ BOOST_CHECK( *(boost::end(rng) - 1) == &o5 );
+
+ // BOOST_CHECK( brdm::test_random_access(rng) ); this range is not mutable
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+void test_CTypedPtrList()
+{
+ typedef ::CTypedPtrList< ::CObList, ::CObList * > rng_t;
+ boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
+
+ rng_t rng;
+
+ ::CObList o1, o2, o3, o4, o5;
+ ::CObList *data[] = { &o1, &o2, &o3, &o4, &o5 };
+ BOOST_CHECK( brdm::test_init_list(rng, data) );
+
+ boost::range_iterator<rng_t>::type it = boost::begin(rng);
+ std::advance(it, 1);
+ BOOST_CHECK( *it == &o2 );
+ std::advance(it, 2);
+ BOOST_CHECK( *it == &o4 );
+
+ // BOOST_CHECK( brdm::test_bidirectional(rng) ); this range is not mutable
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+void test_CTypedPtrMap()
+{
+ typedef ::CTypedPtrMap< ::CMapStringToPtr, ::CString, int *> rng_t;
+ boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
+
+ rng_t rng;
+ ::CString o0(_T('a')), o1(_T('c')), o2(_T('f')), o3(_T('q')), o4(_T('g'));
+ int d0, d1, d2, d3, d4;
+ std::map< ::CString, int * > data;
+ data[o0] = &d0, data[o1] = &d1, data[o2] = &d2, data[o3] = &d3, data[o4] = &d4;
+
+ BOOST_CHECK( brdm::test_init_map(rng, data) );
+ BOOST_CHECK( ::test_mfc_map(rng, data) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+}
+
+
+// strings
+//
+#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+
+ template< class Range >
+ void test_CString(const Range& sample)
+ {
+ typedef typename boost::range_value<Range>::type val_t;
+
+ typedef ::CString rng_t; // An old MFC needs the second template argument.
+ BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, TCHAR *>::value ));
+ BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, TCHAR const*>::value ));
+
+ rng_t rng;
+ BOOST_CHECK( brdm::test_init_string(rng, sample) );
+ BOOST_CHECK( brdm::test_random_access(rng) );
+ BOOST_CHECK( brdm::test_emptiness(rng) );
+ }
+
+#endif
+
+
+struct CPerson
+{
+ void hello_range() { };
+};
+
+
+void test_mfc()
+{
+#if 0
+ // overview
+ //
+ {
+ 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));
+ // ...
+ }
+ }
+ }
+#endif
+
+ // arrays
+ //
+ {
+ BYTE data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
+
+ ::test_CByteArray(boost::make_iterator_range(data, data+22));
+ }
+
+ {
+ DWORD data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
+
+ test_CDWordArray(boost::make_iterator_range(data, data+22));
+ }
+
+ {
+ ::CObArray o1, o2, o3, o4, o5;
+ ::CObject *data[] = { &o1, &o2, &o3, &o4, &o5 };
+
+ ::test_CObArray(boost::make_iterator_range(data, data+5));
+ }
+
+ {
+ ::CPtrArray o1, o2, o3, o4, o5;
+ void *data[] = { &o1, &o2, &o3, &o4, &o5 };
+
+ ::test_CPtrArray(boost::make_iterator_range(data, data+5));
+ }
+
+ {
+ ::CString data[] = {
+ ::CString(_T('0')), ::CString(_T('1')), ::CString(_T('2')), ::CString(_T('3')),
+ ::CString(_T('4')), ::CString(_T('5')), ::CString(_T('6')), ::CString(_T('7'))
+ };
+
+ ::test_CStringArray(boost::make_iterator_range(data, data+8));
+ }
+
+ {
+ ::CUIntArray rng;
+ UINT data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
+
+ ::test_CUIntArray(boost::make_iterator_range(data, data+22));
+ }
+
+ {
+ ::CWordArray rng;
+ WORD data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
+
+ ::test_CWordArray(boost::make_iterator_range(data, data+22));
+ }
+
+
+ // lists
+ //
+ {
+ ::CObList rng;
+ ::CObList o1, o2, o3, o4, o5;
+ ::CObject *data[] = { &o1, &o2, &o3, &o4, &o5 };
+
+ ::test_CObList(boost::make_iterator_range(data, data+5));
+ }
+
+ {
+ ::CPtrList rng;
+ ::CPtrList o1, o2, o3, o4, o5;
+ void *data[] = { &o1, &o2, &o3, &o4, &o5 };
+
+ ::test_CPtrList(boost::make_iterator_range(data, data+5));
+ }
+
+ {
+ ::CString data[] = {
+ ::CString(_T('0')), ::CString(_T('1')), ::CString(_T('2')), ::CString(_T('3')),
+ ::CString(_T('4')), ::CString(_T('5')), ::CString(_T('6')), ::CString(_T('7'))
+ };
+
+ ::test_CStringList(boost::make_iterator_range(data, data+8));
+ }
+
+
+ // maps
+ //
+ {
+ std::map<void *, WORD> data;
+ int o0, o1, o2, o3, o4;
+ data[&o0] = 15, data[&o1] = 14, data[&o2] = 3, data[&o3] = 6, data[&o4] = 1;
+
+ ::test_CMapPtrToWord(data);
+ }
+
+ {
+ std::map<void *, void*> data;
+ int o0, o1, o2, o3, o4;
+ data[&o0] = &o3, data[&o1] = &o2, data[&o2] = &o1, data[&o3] = &o0, data[&o4] = &o4;
+
+ ::test_CMapPtrToPtr(data);
+ }
+
+ {
+ std::map< ::CString, CObject * > data;
+ CObArray o0, o1, o2, o3, o4;
+ data[ ::CString('0') ] = &o0, data[ ::CString('1') ] = &o1, data[ ::CString('2') ] = &o2,
+ data[ ::CString('3') ] = &o3, data[ ::CString('4') ] = &o4;
+
+ ::test_CMapStringToOb(data);
+ }
+
+ {
+ std::map< ::CString, void * > data;
+ CObArray o0, o1, o2, o3, o4;
+ data[ ::CString('0') ] = &o0, data[ ::CString('1') ] = &o1, data[ ::CString('2') ] = &o2,
+ data[ ::CString('3') ] = &o3, data[ ::CString('4') ] = &o4;
+
+ ::test_CMapStringToPtr(data);
+ }
+
+ {
+ std::map< ::CString, ::CString > data;
+ CString o0('a'), o1('b'), o2('c'), o3('d'), o4('e');
+ data[ ::CString('0') ] = o0, data[ ::CString('1') ] = o1, data[ ::CString('2') ] = o2,
+ data[ ::CString('3') ] = o3, data[ ::CString('4') ] = o4;
+
+ ::test_CMapStringToString(data);
+ }
+
+ {
+ std::map< WORD, CObject * > data;
+ ::CDWordArray o0, o1, o2, o3, o4;
+ data[21] = &o3, data[52] = &o2, data[12] = &o1, data[76] = &o0, data[54] = &o4;
+
+ ::test_CMapWordToOb(data);
+ }
+
+ {
+ std::map< WORD, void * > data;
+ ::CDWordArray o0, o1, o2, o3, o4;
+ data[21] = &o3, data[52] = &o2, data[12] = &o1, data[76] = &o0, data[54] = &o4;
+
+ ::test_CMapWordToPtr(data);
+ }
+
+ // templates
+ //
+ {
+ std::string data("0987654321qwertyuiop");
+ ::test_CArray(data);
+ ::test_CList(data);
+ }
+
+ {
+ std::wstring data(L"asdfghjklzxcvbnm");
+ ::test_CArray(data);
+ ::test_CList(data);
+ }
+
+ {
+ std::map< int, std::string > data;
+ data[0] = "abcde", data[1] = "ajfie", data[2] = "lij", data[3] = "abc", data[4] = "ioiu";
+
+ ::test_CMap(data);
+ }
+
+
+ // typed
+ //
+ {
+ ::test_CTypedPtrArray();
+ ::test_CTypedPtrList();
+ ::test_CTypedPtrMap();
+ }
+
+
+ // strings
+ //
+#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
+ {
+ std::string data("123456789 abcdefghijklmn");
+ ::test_CString(data);
+ }
+#endif
+
+
+} // test_mfc
+
+
+#include <boost/test/unit_test.hpp>
+using boost::unit_test::test_suite;
+
+
+test_suite *
+init_unit_test_suite(int argc, char* argv[])
+{
+ test_suite *test = BOOST_TEST_SUITE("MFC Range Test Suite");
+ test->add(BOOST_TEST_CASE(&test_mfc));
+
+ (void)argc, (void)argv; // unused
+ return test;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk