Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85543 - in trunk: boost/utility libs/utility libs/utility/doc libs/utility/test
From: andrey.semashev_at_[hidden]
Date: 2013-09-01 12:31:16


Author: andysem
Date: 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013)
New Revision: 85543
URL: http://svn.boost.org/trac/boost/changeset/85543

Log:
Extracted BOOST_EXPLICIT_OPERATOR_BOOL macro from Boost.Log.

Added:
   trunk/boost/utility/explicit_operator_bool.hpp (contents, props changed)
   trunk/libs/utility/doc/explicit_operator_bool.qbk (contents, props changed)
   trunk/libs/utility/test/explicit_operator_bool.cpp (contents, props changed)
   trunk/libs/utility/test/explicit_operator_bool_compile_fail_conv_int.cpp (contents, props changed)
   trunk/libs/utility/test/explicit_operator_bool_compile_fail_conv_pvoid.cpp (contents, props changed)
   trunk/libs/utility/test/explicit_operator_bool_compile_fail_delete.cpp (contents, props changed)
   trunk/libs/utility/test/explicit_operator_bool_compile_fail_shift.cpp (contents, props changed)
Text files modified:
   trunk/boost/utility/explicit_operator_bool.hpp | 128 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/utility/doc/Jamfile.v2 | 21 +++++
   trunk/libs/utility/doc/explicit_operator_bool.qbk | 68 +++++++++++++++++++++
   trunk/libs/utility/index.html | 1
   trunk/libs/utility/test/Jamfile.v2 | 5 +
   trunk/libs/utility/test/explicit_operator_bool.cpp | 54 ++++++++++++++++
   trunk/libs/utility/test/explicit_operator_bool_compile_fail_conv_int.cpp | 40 ++++++++++++
   trunk/libs/utility/test/explicit_operator_bool_compile_fail_conv_pvoid.cpp | 40 ++++++++++++
   trunk/libs/utility/test/explicit_operator_bool_compile_fail_delete.cpp | 40 ++++++++++++
   trunk/libs/utility/test/explicit_operator_bool_compile_fail_shift.cpp | 40 ++++++++++++
   10 files changed, 435 insertions(+), 2 deletions(-)

Added: trunk/boost/utility/explicit_operator_bool.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/utility/explicit_operator_bool.hpp 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -0,0 +1,128 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file explicit_operator_bool.hpp
+ * \author Andrey Semashev
+ * \date 08.03.2009
+ *
+ * This header defines a compatibility macro that implements an unspecified
+ * \c bool operator idiom, which is superseded with explicit conversion operators in
+ * C++11.
+ */
+
+#ifndef BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
+#define BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+/*!
+ * \brief The macro defines an explicit operator of conversion to \c bool
+ *
+ * The macro should be used inside the definition of a class that has to
+ * support the conversion. The class should also implement <tt>operator!</tt>,
+ * in terms of which the conversion operator will be implemented.
+ */
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE explicit operator bool () const\
+ {\
+ return !this->operator! ();\
+ }
+
+/*!
+ * \brief The macro defines a constexpr explicit operator of conversion to \c bool
+ *
+ * The macro should be used inside the definition of a class that has to
+ * support the conversion. The class should also implement <tt>operator!</tt>,
+ * in terms of which the conversion operator will be implemented.
+ */
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE BOOST_CONSTEXPR explicit operator bool () const\
+ {\
+ return !this->operator! ();\
+ }
+
+#else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
+// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
+#define BOOST_NO_UNSPECIFIED_BOOL
+#endif // (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
+
+#if !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+namespace boost {
+
+namespace detail {
+
+#if !defined(_MSC_VER)
+
+ struct unspecified_bool
+ {
+ // NOTE TO THE USER: If you see this in error messages then you tried
+ // to apply an unsupported operator on the object that supports
+ // explicit conversion to bool.
+ struct OPERATORS_NOT_ALLOWED;
+ static void true_value(OPERATORS_NOT_ALLOWED*) {}
+ };
+ typedef void (*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
+
+#else
+
+ // MSVC is too eager to convert pointer to function to void* even though it shouldn't
+ struct unspecified_bool
+ {
+ // NOTE TO THE USER: If you see this in error messages then you tried
+ // to apply an unsupported operator on the object that supports
+ // explicit conversion to bool.
+ struct OPERATORS_NOT_ALLOWED;
+ void true_value(OPERATORS_NOT_ALLOWED*) {}
+ };
+ typedef void (unspecified_bool::*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
+
+#endif
+
+} // namespace detail
+
+} // namespace boost
+
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const\
+ {\
+ return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
+ }
+
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE BOOST_CONSTEXPR operator boost::detail::unspecified_bool_type () const\
+ {\
+ return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
+ }
+
+#else // !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE operator bool () const\
+ {\
+ return !this->operator! ();\
+ }
+
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE BOOST_CONSTEXPR operator bool () const\
+ {\
+ return !this->operator! ();\
+ }
+
+#endif // !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+#endif // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+#endif // BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_

Modified: trunk/libs/utility/doc/Jamfile.v2
==============================================================================
--- trunk/libs/utility/doc/Jamfile.v2 Sun Sep 1 07:15:01 2013 (r85542)
+++ trunk/libs/utility/doc/Jamfile.v2 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -6,7 +6,7 @@
 project : requirements
         # Path for links to Boost:
         <xsl:param>boost.root=../../../..
-
+
         # Some general style settings:
         <xsl:param>table.footnote.number.format=1
         <xsl:param>footnote.number.format=1
@@ -59,7 +59,6 @@
         <xsl:param>toc.max.depth=1
         # How far down we go with TOC's
         <xsl:param>generate.section.toc.level=1
-
      ;
 
 xml string_ref : string_ref.qbk ;
@@ -79,5 +78,23 @@
         <xsl:param>toc.max.depth=1
         # How far down we go with TOC's
         <xsl:param>generate.section.toc.level=1
+ ;
 
+xml explicit_operator_bool : explicit_operator_bool.qbk ;
+boostbook standalone_explicit_operator_bool
+ :
+ explicit_operator_bool
+ :
+ # File name of HTML output:
+ <xsl:param>root.filename=explicit_operator_bool
+ # How far down we chunk nested sections, basically all of them:
+ <xsl:param>chunk.section.depth=0
+ # Don't put the first section on the same page as the TOC:
+ <xsl:param>chunk.first.sections=0
+ # How far down sections get TOC's
+ <xsl:param>toc.section.depth=1
+ # Max depth in each TOC:
+ <xsl:param>toc.max.depth=1
+ # How far down we go with TOC's
+ <xsl:param>generate.section.toc.level=1
      ;

Added: trunk/libs/utility/doc/explicit_operator_bool.qbk
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/utility/doc/explicit_operator_bool.qbk 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -0,0 +1,68 @@
+[/
+ / Copyright (c) 2013 Andrey Semashev
+ /
+ / 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)
+ /]
+
+[article BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL
+ [quickbook 1.5]
+ [authors [Semashev, Andrey]]
+ [copyright 2013 Andrey Semashev]
+ [license
+ 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])
+ ]
+]
+
+[/===============]
+[section Overview]
+[/===============]
+
+`BOOST_EXPLICIT_OPERATOR_BOOL()` and `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` are compatibility helper macros that expand to an explicit conversion operator to `bool`. For compilers not supporting explicit conversion operators introduced in C++11 the macros expand to a conversion operator that implements the [@http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool safe bool idiom]. In case if the compiler is not able to handle safe bool idiom well the macros expand to a regular conversion operator to `bool`.
+
+[endsect]
+
+
+[/===============]
+[section Examples]
+[/===============]
+
+Both macros are intended to be placed within a user's class definition. The generated conversion operators will be implemented in terms of `operator!()` that should be defined by user in this class. In case of `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` the generated conversion operator will be declared `constexpr` which requires the corresponding `operator!()` to also be `constexpr`.
+
+ template< typename T >
+ class my_ptr
+ {
+ T* m_p;
+
+ public:
+ BOOST_EXPLICIT_OPERATOR_BOOL()
+
+ bool operator!() const
+ {
+ return !m_p;
+ }
+ };
+
+Now `my_ptr` can be used in conditional expressions, similarly to a regular pointer:
+
+ my_ptr< int > p;
+ if (p)
+ std::cout << "true" << std::endl;
+
+[endsect]
+
+[/===============]
+[section History]
+[/===============]
+
+[heading boost 1.55]
+
+* The macro was extracted from Boost.Log.
+
+[endsect]
+
+
+
+

Modified: trunk/libs/utility/index.html
==============================================================================
--- trunk/libs/utility/index.html Sun Sep 1 07:15:01 2013 (r85542)
+++ trunk/libs/utility/index.html 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -36,6 +36,7 @@
                                 <a href="utility.htm">utility</a><br>
             <a href="doc/html/string_ref.html">string_ref</a><br>
             <a href="value_init.htm">value_init</a>
+ BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL<br>
          </p>
                 </blockquote>
                 <hr>

Modified: trunk/libs/utility/test/Jamfile.v2
==============================================================================
--- trunk/libs/utility/test/Jamfile.v2 Sun Sep 1 07:15:01 2013 (r85542)
+++ trunk/libs/utility/test/Jamfile.v2 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -48,5 +48,10 @@
         [ compile-fail ../initialized_test_fail1.cpp ]
         [ compile-fail ../initialized_test_fail2.cpp ]
         [ run ../verify_test.cpp ]
+ [ run explicit_operator_bool.cpp ]
+ [ compile-fail explicit_operator_bool_compile_fail_conv_int.cpp ]
+ [ compile-fail explicit_operator_bool_compile_fail_conv_pvoid.cpp ]
+ [ compile-fail explicit_operator_bool_compile_fail_delete.cpp ]
+ [ compile-fail explicit_operator_bool_compile_fail_shift.cpp ]
     ;
 

Added: trunk/libs/utility/test/explicit_operator_bool.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/utility/test/explicit_operator_bool.cpp 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -0,0 +1,54 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file explicit_operator_bool_compile.cpp
+ * \author Andrey Semashev
+ * \date 17.07.2010
+ *
+ * \brief This test checks that explicit operator bool can be used in
+ * the valid contexts.
+ */
+
+#define BOOST_TEST_MODULE explicit_operator_bool_compile
+
+#include <boost/utility/explicit_operator_bool.hpp>
+
+namespace {
+
+ // A test object that has the operator of explicit conversion to bool
+ struct checkable1
+ {
+ BOOST_EXPLICIT_OPERATOR_BOOL()
+ bool operator! () const
+ {
+ return false;
+ }
+ };
+
+ struct checkable2
+ {
+ BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()
+ BOOST_CONSTEXPR bool operator! () const
+ {
+ return false;
+ }
+ };
+
+} // namespace
+
+int main(int, char*[])
+{
+ checkable1 val1;
+ if (val1)
+ {
+ checkable2 val2;
+ if (val2)
+ return 0;
+ }
+
+ return 1;
+}

Added: trunk/libs/utility/test/explicit_operator_bool_compile_fail_conv_int.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/utility/test/explicit_operator_bool_compile_fail_conv_int.cpp 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -0,0 +1,40 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file explicit_operator_bool_compile_fail_conv_int.cpp
+ * \author Andrey Semashev
+ * \date 17.07.2010
+ *
+ * \brief This test checks that explicit operator bool cannot be used in
+ * an unintended context.
+ */
+
+#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_conv_int
+
+#include <boost/utility/explicit_operator_bool.hpp>
+
+namespace {
+
+ // A test object that has the operator of explicit conversion to bool
+ struct checkable
+ {
+ BOOST_EXPLICIT_OPERATOR_BOOL()
+ bool operator! () const
+ {
+ return false;
+ }
+ };
+
+} // namespace
+
+int main(int, char*[])
+{
+ checkable val;
+ int n = val;
+
+ return 0;
+}

Added: trunk/libs/utility/test/explicit_operator_bool_compile_fail_conv_pvoid.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/utility/test/explicit_operator_bool_compile_fail_conv_pvoid.cpp 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -0,0 +1,40 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file explicit_operator_bool_compile_fail_conv_pvoid.cpp
+ * \author Andrey Semashev
+ * \date 17.07.2010
+ *
+ * \brief This test checks that explicit operator bool cannot be used in
+ * an unintended context.
+ */
+
+#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_conv_pvoid
+
+#include <boost/utility/explicit_operator_bool.hpp>
+
+namespace {
+
+ // A test object that has the operator of explicit conversion to bool
+ struct checkable
+ {
+ BOOST_EXPLICIT_OPERATOR_BOOL()
+ bool operator! () const
+ {
+ return false;
+ }
+ };
+
+} // namespace
+
+int main(int, char*[])
+{
+ checkable val;
+ void* p = val;
+
+ return 0;
+}

Added: trunk/libs/utility/test/explicit_operator_bool_compile_fail_delete.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/utility/test/explicit_operator_bool_compile_fail_delete.cpp 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -0,0 +1,40 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file explicit_operator_bool_compile_fail_delete.cpp
+ * \author Andrey Semashev
+ * \date 17.07.2010
+ *
+ * \brief This test checks that explicit operator bool cannot be used in
+ * an unintended context.
+ */
+
+#define BOOST_TEST_MODULE util_explicit_operator_bool_delete
+
+#include <boost/utility/explicit_operator_bool.hpp>
+
+namespace {
+
+ // A test object that has the operator of explicit conversion to bool
+ struct checkable
+ {
+ BOOST_EXPLICIT_OPERATOR_BOOL()
+ bool operator! () const
+ {
+ return false;
+ }
+ };
+
+} // namespace
+
+int main(int, char*[])
+{
+ checkable val;
+ delete val;
+
+ return 0;
+}

Added: trunk/libs/utility/test/explicit_operator_bool_compile_fail_shift.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/utility/test/explicit_operator_bool_compile_fail_shift.cpp 2013-09-01 12:31:16 EDT (Sun, 01 Sep 2013) (r85543)
@@ -0,0 +1,40 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file explicit_operator_bool_compile_fail_shift.cpp
+ * \author Andrey Semashev
+ * \date 17.07.2010
+ *
+ * \brief This test checks that explicit operator bool cannot be used in
+ * an unintended context.
+ */
+
+#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_shift
+
+#include <boost/utility/explicit_operator_bool.hpp>
+
+namespace {
+
+ // A test object that has the operator of explicit conversion to bool
+ struct checkable
+ {
+ BOOST_EXPLICIT_OPERATOR_BOOL()
+ bool operator! () const
+ {
+ return false;
+ }
+ };
+
+} // namespace
+
+int main(int, char*[])
+{
+ checkable val;
+ val << 2;
+
+ return 0;
+}


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