mirror of
https://github.com/boostorg/core.git
synced 2025-05-11 05:07:39 +00:00
Extracted BOOST_EXPLICIT_OPERATOR_BOOL macro from Boost.Log.
[SVN r85543]
This commit is contained in:
parent
c63c917ebe
commit
e9a53f2e69
68
doc/explicit_operator_bool.qbk
Normal file
68
doc/explicit_operator_bool.qbk
Normal file
@ -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]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
128
include/boost/utility/explicit_operator_bool.hpp
Normal file
128
include/boost/utility/explicit_operator_bool.hpp
Normal file
@ -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_
|
54
test/explicit_operator_bool.cpp
Normal file
54
test/explicit_operator_bool.cpp
Normal file
@ -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;
|
||||||
|
}
|
40
test/explicit_operator_bool_compile_fail_conv_int.cpp
Normal file
40
test/explicit_operator_bool_compile_fail_conv_int.cpp
Normal file
@ -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;
|
||||||
|
}
|
40
test/explicit_operator_bool_compile_fail_conv_pvoid.cpp
Normal file
40
test/explicit_operator_bool_compile_fail_conv_pvoid.cpp
Normal file
@ -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;
|
||||||
|
}
|
40
test/explicit_operator_bool_compile_fail_delete.cpp
Normal file
40
test/explicit_operator_bool_compile_fail_delete.cpp
Normal file
@ -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;
|
||||||
|
}
|
40
test/explicit_operator_bool_compile_fail_shift.cpp
Normal file
40
test/explicit_operator_bool_compile_fail_shift.cpp
Normal file
@ -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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user