Index: libs/utility/operators.htm
===================================================================
RCS file: /cvsroot/boost/boost/libs/utility/operators.htm,v
retrieving revision 1.12
diff -u -r1.12 operators.htm
--- libs/utility/operators.htm	4 Nov 2002 01:59:31 -0000	1.12
+++ libs/utility/operators.htm	12 Mar 2003 19:08:13 -0000
@@ -340,6 +340,8 @@
 
       <li><code><a href="#indexable">indexable&lt;&gt;</a></code></li>
 
+      <li><code><a href="#bool_testable">bool_testable&lt;&gt;</a></code></li>
+
       <li>Any composite operator template that includes at least one of the
       above</li>
     </ul>
@@ -528,6 +530,17 @@
       </tr>
 
       <tr>
+        <td><code><a name="bool_testable">bool_testable&lt;T&gt;</a></code></
+        td>
+
+        <td><code>bool operator!(const T&)</code></td>
+
+        <td><code>static_cast&lt;bool&gt;(t)</code>.<br>
+         <code>T</code> convertible to <code>bool</code>. See the <a href=
+         "#bool_testable_note">bool_testable Note</a>.</td>
+      </tr>
+
+      <tr>
         <td><code><a name="addable1">addable&lt;T&gt;</a></code><br>
          <code>addable1&lt;T&gt;</code></td>
 
@@ -974,7 +987,123 @@
     that don't implement the NRVO. <br>
      <br>
      
+    <h4><a name="bool_testable_note">Bool Testable</a> Note</h4>
+
+    <p><code><a href="#bool_testable">bool_testable</a></code> provides the
+    opposite of operator bool, such that the expression <code>if (!p)</code> is 
+    valid, whilst also making <code>operator bool</code> safer by preventing 
+    accidental conversions to integer types.  If <code>operator bool</code>
+    were declared without using 
+    <code><a href="#bool_testable">bool_testable</code></a> then expressions
+    such as :</p>
+
+<pre>
+void f(int);
+
+void g(object o)
+{
+    f(o);
+}
+</pre>
+
+    <p>would compile silently, not warning the user of the (probably) 
+    unintended behaviour of passing <code>0</code> or <code>1</code> to 
+    <code>f()</code>.</p> <code>bool_testable&lt;&gt;</code> prevents these 
+    accidental conversions by declaring an <code>operator signed char()</code>
+    private, and not defining the body.</p>
+
+    <h5>Example :</h5>
+
+<pre>
+class Stream : boost::bool_testable&lt;Stream&gt;
+{
+public:
+    explicit Stream(const char * source);
+    operator bool() const;
+    // non-member bool operator!(const T&) const auto-generated and 
+    // operator bool made safe by bool_testable&lt;&gt;
+
+    bool can_print();
+};
+
+void g(int);
+
+void f()
+{
+    if (Stream s1("source.txt"))
+    {
+        // use s1 ...
+    }
+
+    // or..
+
+    Stream s2("source.txt");
+    if (!s2)
+    {
+        // handle problem
+    }
 
+    // or ..
+
+    if (s2 && s2.can_print()) // see <a href="#bool_testable_msvc">note</a>
+    {
+        // print something...
+    }
+
+    g(stream); // Will not compile, but would compile 
+               // fine without bool_testable&lt;&gt;
+}
+</pre>
+
+    <h5><a name="bool_testable_msvc">Note for MSVC version 6 users</a> :</h5>
+
+    <p>Due to a bug in MSVC6, whilst compiling the above code, the compiler 
+    will incorrectly complain of '<code>ambiguous operator &&</code>' at
+    line 30.  The workaround for this is to either:</p>
+<pre>
+    if (stream)
+        if (stream.can_print())
+</pre>
+    <p>or</p>
+<pre>
+    if (!!stream && stream.can_print())
+</pre>
+    <p>This also affects <code>logical operator ||</code>.</p>
+
+    <h5>Rationale for Implementation</h5>
+
+    <p>Another possible implementation for <code>bool_testable</code> was the
+    safe-bool idiom as found in <a href=
+    "../smart_ptr/shared_ptr.htm#conversions"><code>shared_ptr&lt;&gt;</code>
+    </a>.  This implementation required the user to provide 
+    <code>operator!</code>, and provided an 
+    <code>operator unspecified-bool-type()</code> conversion in return.  It had
+    the advantage of slight more descriptive diagnostic messages in the case of 
+    syntax errors.  But this implementation had issues when used with a class 
+    with user defined integer conversion operators.  For example:</p>
+
+<pre>
+class MyInt : alternative_bool_testable&lt;MyInt&gt;
+{
+public:
+    bool operator!() const;
+    operator int() const;
+};
+
+void g(int);
+
+void f(const MyInt& i)
+{
+    if (!i) // fine: calls operator!
+        ...
+
+    g(i);   // fine: calls operator int
+
+    if (i)  // error: calls operator int NOT operator unspecified-bool-type()
+        ...
+}
+</pre>
+    
     <h3><a name="grpd_oprs">Grouped Arithmetic Operators</a></h3>
 
     <p>The following templates provide common groups of related operations.
@@ -2062,6 +2191,12 @@
 
       <dd>Contributed the NRVO-friendly and symmetric implementation of
       arithmetic operators.</dd>
+
+      <dt>Sam Partington</dt>
+
+      <dd>Contributed the bool_testable class, assisted by Daniel Frey and
+      David Abrahams.</dd>
+
     </dl>
 
     <h2>Note for Users of <a name="old_lib_note">Older Versions</a></h2>
