From 2f5945d0cd075f910d6477f3e426d51b11b1ebf5 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Wed, 3 Dec 2003 07:01:28 +0000 Subject: [PATCH] Removed bool_testable, added note about portability of separate, explicit instantiation, changed license of documentation [SVN r21110] --- include/boost/operators.hpp | 17 ---- operators.htm | 168 ++++-------------------------------- operators_test.cpp | 22 ----- safe_bool_testable_test.cpp | 37 -------- test/Jamfile | 1 - test/Jamfile.v2 | 1 - 6 files changed, 17 insertions(+), 229 deletions(-) delete mode 100644 safe_bool_testable_test.cpp diff --git a/include/boost/operators.hpp b/include/boost/operators.hpp index cd4b76f..1833367 100644 --- a/include/boost/operators.hpp +++ b/include/boost/operators.hpp @@ -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 -struct bool_testable : B -{ - friend bool operator!(const T& t) { return !static_cast(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) diff --git a/operators.htm b/operators.htm index 236ebc6..440ee4d 100644 --- a/operators.htm +++ b/operators.htm @@ -72,8 +72,6 @@
  • Ordering Note
  • Symmetry Note
  • - -
  • Safe-Bool Note
  • @@ -342,12 +340,19 @@ class MyInt
  • indexable<>
  • -
  • bool_testable<>
  • -
  • Any composite operator template that includes at least one of the above
  • +

    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. + less_than_comparable<myclass> can not be found + by ADL according to the rules given by 3.4.2/2, since myclass is + not an associated class of + less_than_comparable<myclass>. + Thus only use this technique if all else fails.

    +

    Requirement Portability

    Many compilers (e.g. 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 bool. - - bool_testable<T> - - bool operator!(const T&) - - static_cast<bool>(t).
    - T convertible to bool. See the Safe-Bool Note. - - addable<T>
    addable1<T> @@ -989,132 +983,6 @@ T operator+( T lhs, const T& rhs ) that don't implement the NRVO.

    -

    Safe-Bool Note

    - -

    bool_testable provides the - antithesis of operator bool, such that the expression if (!p) - is valid, whilst also making operator bool safer by preventing - accidental conversions to integer types. If operator bool - were declared for a class without using - bool_testable then expressions - such as :

    - -
    -void f(int);
    -
    -void g(object o)
    -{
    -    f(o);
    -}
    -
    - -

    would compile silently, not warning the user of the (probably) - unintended behaviour of passing 0 or 1 to - f().

    bool_testable<> prevents these - accidental conversions by declaring a private conversion operator to - signed char, and not defining the body.

    - -
    Example :
    - -
    -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 note
    -    {
    -        // print something...
    -    }
    -
    -    g(stream); // Will not compile, but would compile 
    -               // fine without bool_testable<>
    -}
    -
    - -
    Note for MSVC version 6 users :
    - -

    Due to a bug in MSVC6, whilst compiling the above code, the compiler - will incorrectly diagnose an 'ambiguous operator &&' at - the asterisked line. The workaround for this is to either:

    -
    -    if (s2)
    -        if (s2.can_print())
    -
    -

    or

    -
    -    if (!!s2 && s2.can_print())
    -
    -

    This problem also affects the other logical operators.

    - -
    Rationale for Implementation
    - -

    Another possible implementation for bool_testable was the - safe-bool idiom as found in shared_ptr<> - written by Peter Dimov. - This implementation required the user to provide operator!, - 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:

    - -
    -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()
    -        ...
    -}
    -
    -

    Grouped Arithmetic Operators

    The following templates provide common groups of related operations. @@ -2203,10 +2071,6 @@ public:

    Contributed the NRVO-friendly and symmetric implementation of arithmetic operators.
    -
    Sam Partington
    - -
    Contributed the bool_testable class.
    -

    Note for Users of Older Versions

    @@ -2255,13 +2119,15 @@ public: backward-compatible.


    -

    Revised: 30 Oct 2001

    +

    Revised: 03 Dec 2003

    -

    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.

    +

    Copyright © Beman Dawes, David Abrahams, 1999-2001.

    +

    Copyright © Daniel Frey, 2002-2003.

    +

    Use, modification, and distribution is subject to 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/operators_test.cpp b/operators_test.cpp index 0efe9dc..c67da10 100644 --- a/operators_test.cpp +++ b/operators_test.cpp @@ -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 > , boost::shiftable > - , boost::bool_testable > { 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; #define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) ) -#define PRIVATE_BOOLEAN_EXPR_TEST(t, res) BOOST_TEST(static_cast((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 ); diff --git a/safe_bool_testable_test.cpp b/safe_bool_testable_test.cpp deleted file mode 100644 index 0a072d2..0000000 --- a/safe_bool_testable_test.cpp +++ /dev/null @@ -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 - -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 diff --git a/test/Jamfile b/test/Jamfile index edf8902..8f72ec7 100755 --- a/test/Jamfile +++ b/test/Jamfile @@ -23,7 +23,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 ] diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9c47e91..0c65556 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -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 ]