mirror of
https://github.com/boostorg/utility.git
synced 2025-05-09 15:04:00 +00:00
Removed bool_testable, added note about portability of separate, explicit instantiation, changed license of documentation
[SVN r21110]
This commit is contained in:
parent
929517d6d7
commit
2f5945d0cd
@ -9,7 +9,6 @@
|
||||
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||
|
||||
// Revision History
|
||||
// 04 May 05 Added operator class bool_testable. (Sam Partington)
|
||||
// 21 Oct 02 Modified implementation of operators to allow compilers with a
|
||||
// correct named return value optimization (NRVO) to produce optimal
|
||||
// code. (Daniel Frey)
|
||||
@ -309,20 +308,6 @@ struct indexable : B
|
||||
}
|
||||
};
|
||||
|
||||
// bool_testable -----------------------------------------------------------//
|
||||
// (contributed by Sam Partington, David Abrahams and Daniel Frey) ---------//
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct bool_testable : B
|
||||
{
|
||||
friend bool operator!(const T& t) { return !static_cast<bool>(t); }
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
private:
|
||||
typedef signed char private_number_type;
|
||||
operator private_number_type() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
// More operator classes (contributed by Daryle Walker) --------------------//
|
||||
// (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
|
||||
|
||||
@ -831,8 +816,6 @@ BOOST_OPERATOR_TEMPLATE1(decrementable)
|
||||
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
||||
BOOST_OPERATOR_TEMPLATE3(indexable)
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE1(bool_testable)
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE(left_shiftable)
|
||||
BOOST_OPERATOR_TEMPLATE(right_shiftable)
|
||||
BOOST_OPERATOR_TEMPLATE(equivalent)
|
||||
|
168
operators.htm
168
operators.htm
@ -72,8 +72,6 @@
|
||||
<li><a href="#ordering">Ordering Note</a></li>
|
||||
|
||||
<li><a href="#symmetry">Symmetry Note</a></li>
|
||||
|
||||
<li><a href="#safe_bool_note">Safe-Bool Note</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@ -342,12 +340,19 @@ class MyInt
|
||||
|
||||
<li><code><a href="#indexable">indexable<></a></code></li>
|
||||
|
||||
<li><code><a href="#bool_testable">bool_testable<></a></code></li>
|
||||
|
||||
<li>Any composite operator template that includes at least one of the
|
||||
above</li>
|
||||
</ul>
|
||||
|
||||
<p>As Daniel Krügler pointed out, this technique violates 14.6.5/2
|
||||
and is thus non-portable. The reasoning is, that the operators injected
|
||||
by the instantiation of e.g.
|
||||
<code>less_than_comparable<myclass></code> can not be found
|
||||
by ADL according to the rules given by 3.4.2/2, since myclass is
|
||||
not an associated class of
|
||||
<code>less_than_comparable<myclass></code>.
|
||||
Thus only use this technique if all else fails.</p>
|
||||
|
||||
<h3>Requirement <a name="portability">Portability</a></h3>
|
||||
|
||||
<p>Many compilers (<i>e.g.</i> MSVC 6.3, GCC 2.95.2) will not enforce the
|
||||
@ -531,17 +536,6 @@ const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
|
||||
Return convertible to <code>bool</code>.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code><a name="bool_testable">bool_testable<T></a></code></
|
||||
td>
|
||||
|
||||
<td><code>bool operator!(const T&)</code></td>
|
||||
|
||||
<td><code>static_cast<bool>(t)</code>.<br>
|
||||
<code>T</code> convertible to <code>bool</code>. See the <a href=
|
||||
"#safe_bool_note">Safe-Bool Note</a>.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code><a name="addable1">addable<T></a></code><br>
|
||||
<code>addable1<T></code></td>
|
||||
@ -989,132 +983,6 @@ T operator+( T lhs, const T& rhs )
|
||||
that don't implement the NRVO. <br>
|
||||
<br>
|
||||
|
||||
<h4><a name="safe_bool_note">Safe-Bool</a> Note</h4>
|
||||
|
||||
<p><code><a href="#bool_testable">bool_testable</a></code> provides the
|
||||
antithesis 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 for a class 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<></code> prevents these
|
||||
accidental conversions by declaring a private conversion operator to
|
||||
<code>signed char</code>, and not defining the body.</p>
|
||||
|
||||
<h5>Example :</h5>
|
||||
|
||||
<pre>
|
||||
class Stream : boost::bool_testable<Stream>
|
||||
{
|
||||
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<>
|
||||
|
||||
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<>
|
||||
}
|
||||
</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 diagnose an '<code>ambiguous operator &&</code>' at
|
||||
the asterisked line. The workaround for this is to either:</p>
|
||||
<pre>
|
||||
if (s2)
|
||||
if (s2.can_print())
|
||||
</pre>
|
||||
<p>or</p>
|
||||
<pre>
|
||||
if (!!s2 && s2.can_print())
|
||||
</pre>
|
||||
<p>This problem also affects the other logical operators.</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<></code>
|
||||
</a> written by <a href="../../people/peter_dimov.htm">Peter Dimov</a>.
|
||||
This implementation required the user to provide <code>operator!</code>,
|
||||
and provided a conversion operator to a pointer to member function. This
|
||||
method had the advantage of more descriptive diagnostic messages on most
|
||||
platforms, when the bool conversion was used incorrectly. Unfortunately
|
||||
that implementation had issues when used with a class with other user
|
||||
defined integer conversion operators. This is because the integer
|
||||
conversion operator provided a better match than the conversion to pointer
|
||||
to member function. For example:</p>
|
||||
|
||||
<pre>
|
||||
class MyInt : alternative_bool_testable<MyInt>
|
||||
{
|
||||
public:
|
||||
bool operator!() const;
|
||||
operator int() const;
|
||||
|
||||
// alternative_bool_testable<MyInt> provides :
|
||||
//
|
||||
// typedef void (MyInt::*member_fn)();
|
||||
// operator member_fn() { return &MyInt::f; }
|
||||
|
||||
};
|
||||
|
||||
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 member_fn()
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3><a name="grpd_oprs">Grouped Arithmetic Operators</a></h3>
|
||||
|
||||
<p>The following templates provide common groups of related operations.
|
||||
@ -2203,10 +2071,6 @@ public:
|
||||
<dd>Contributed the NRVO-friendly and symmetric implementation of
|
||||
arithmetic operators.</dd>
|
||||
|
||||
<dt>Sam Partington</dt>
|
||||
|
||||
<dd>Contributed the bool_testable class.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h2>Note for Users of <a name="old_lib_note">Older Versions</a></h2>
|
||||
@ -2255,13 +2119,15 @@ public:
|
||||
backward-compatible.</p>
|
||||
<hr>
|
||||
|
||||
<p>Revised: 30 Oct 2001</p>
|
||||
<p>Revised: 03 Dec 2003</p>
|
||||
|
||||
<p>Copyright © David Abrahams and Beman Dawes 1999-2001. Permission
|
||||
to copy, use, modify, sell and distribute this document is granted
|
||||
provided this copyright notice appears in all copies. This document is
|
||||
provided "as is" without express or implied warranty, and with no claim
|
||||
as to its suitability for any purpose.</p>
|
||||
<p>Copyright © Beman Dawes, David Abrahams, 1999-2001.</p>
|
||||
<p>Copyright © Daniel Frey, 2002-2003.</p>
|
||||
<p>Use, modification, and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file
|
||||
<a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
// See http://www.boost.org/libs/utility for documentation.
|
||||
|
||||
// Revision History
|
||||
// 23 May 03 Added tests for "bool_testable". (Sam Partington/Daniel Frey)
|
||||
// 01 Oct 01 Added tests for "left" operators
|
||||
// and new grouped operators. (Helmut Zeisel)
|
||||
// 20 May 01 Output progress messages. Added tests for new operator
|
||||
@ -49,7 +48,6 @@ namespace
|
||||
class Wrapped1
|
||||
: boost::operators<Wrapped1<T> >
|
||||
, boost::shiftable<Wrapped1<T> >
|
||||
, boost::bool_testable<Wrapped1<T> >
|
||||
{
|
||||
public:
|
||||
explicit Wrapped1( T v = T() ) : _value(v) {}
|
||||
@ -80,7 +78,6 @@ namespace
|
||||
{ _value >>= x._value; return *this; }
|
||||
Wrapped1& operator++() { ++_value; return *this; }
|
||||
Wrapped1& operator--() { --_value; return *this; }
|
||||
operator bool() const { return _value != 0; }
|
||||
|
||||
private:
|
||||
T _value;
|
||||
@ -565,13 +562,6 @@ template Wrapped6<unsigned int, unsigned char>;
|
||||
|
||||
#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
|
||||
|
||||
#define PRIVATE_BOOLEAN_EXPR_TEST(t, res) BOOST_TEST(static_cast<bool>((t)) == (res))
|
||||
#if defined(BOOST_MSVC)
|
||||
#define PRIVATE_MSVC_BOOL_TEST_WORKAROUND(x) (!!x)
|
||||
#else
|
||||
#define PRIVATE_MSVC_BOOL_TEST_WORKAROUND(x) (x)
|
||||
#endif
|
||||
|
||||
int
|
||||
test_main( int , char * [] )
|
||||
{
|
||||
@ -621,18 +611,6 @@ test_main( int , char * [] )
|
||||
|
||||
cout << "Created MyInt objects.\n";
|
||||
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( i, false );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( i1, true );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( i2, true );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( !i, true );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( !i1, false );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( !i2, false );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( PRIVATE_MSVC_BOOL_TEST_WORKAROUND(i) && PRIVATE_MSVC_BOOL_TEST_WORKAROUND(i2), false );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( PRIVATE_MSVC_BOOL_TEST_WORKAROUND(i) || PRIVATE_MSVC_BOOL_TEST_WORKAROUND(i2), true );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( PRIVATE_MSVC_BOOL_TEST_WORKAROUND(i1) && PRIVATE_MSVC_BOOL_TEST_WORKAROUND(i2), true );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( !i && PRIVATE_MSVC_BOOL_TEST_WORKAROUND(i2), true );
|
||||
PRIVATE_BOOLEAN_EXPR_TEST( PRIVATE_MSVC_BOOL_TEST_WORKAROUND(i1) && !i, true );
|
||||
|
||||
PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
|
||||
|
||||
BOOST_TEST( i2 == i );
|
||||
|
@ -1,37 +0,0 @@
|
||||
// Boost safe_bool_testable test program -----------------------------------//
|
||||
|
||||
// (C) Copyright Daniel Frey 2003. Permission to copy, use, modify, sell
|
||||
// and distribute this software is granted provided this copyright
|
||||
// notice appears in all copies. This software is provided "as is" without
|
||||
// express or implied warranty, and with no claim as to its suitability for
|
||||
// any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 30 Jul 03 Initial version (Daniel Frey)
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct X
|
||||
: private boost::bool_testable< X >
|
||||
{
|
||||
operator bool() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
X x;
|
||||
|
||||
int i = x; // Should cause compile time error
|
||||
|
||||
i = i; // Surpress warnings which has nothing to do with the test
|
||||
|
||||
return 0;
|
||||
} // main
|
@ -23,7 +23,6 @@ test-suite utility
|
||||
[ compile-fail ../noncopyable_test.cpp ]
|
||||
[ run ../numeric_traits_test.cpp ]
|
||||
[ run ../operators_test.cpp <lib>../../test/build/boost_test_exec_monitor ]
|
||||
[ compile-fail ../safe_bool_testable_test.cpp ]
|
||||
[ run ../binary_search_test.cpp <lib>../../test/build/boost_test_exec_monitor ]
|
||||
[ run ../call_traits_test.cpp : -u ]
|
||||
[ compile-fail ../checked_delete_test.cpp ]
|
||||
|
@ -16,7 +16,6 @@ test-suite utility
|
||||
[ compile-fail ../noncopyable_test.cpp ]
|
||||
[ run ../numeric_traits_test.cpp ]
|
||||
[ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ compile-fail ../safe_bool_testable_test.cpp ]
|
||||
[ run ../binary_search_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ run ../call_traits_test.cpp : -u ]
|
||||
[ compile-fail ../checked_delete_test.cpp ]
|
||||
|
Loading…
x
Reference in New Issue
Block a user