diff --git a/include/boost/logic/tribool.hpp b/include/boost/logic/tribool.hpp index 0686beb..041c59c 100644 --- a/include/boost/logic/tribool.hpp +++ b/include/boost/logic/tribool.hpp @@ -71,6 +71,7 @@ indeterminate(tribool x, */ class tribool { +#if defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) private: /// INTERNAL ONLY struct dummy { @@ -78,6 +79,7 @@ private: }; typedef void (dummy::*safe_bool)(); +#endif public: /** diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 20c1ba7..994f2b6 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -8,10 +8,55 @@ # For more information, see http://www.boost.org/ +import path ; +import os ; +import regex ; +import testing ; + +local self = logic ; + +rule test-expected-failures +{ + local all_rules = ; + local file ; + local tests_path = [ path.make $(BOOST_ROOT)/libs/$(self)/test/compile-fail ] ; + for file in [ path.glob-tree $(tests_path) : *.cpp ] + { + local rel_file = [ path.relative-to $(tests_path) $(file) ] ; + local test_name = [ regex.replace [ regex.replace $(rel_file) "/" "-" ] ".cpp" "" ] ; + local decl_test_name = cf-$(test_name) ; + # ECHO $(rel_file) ; + all_rules += [ compile-fail $(file) : : $(decl_test_name) ] ; + } + + # ECHO All rules: $(all_rules) ; + return $(all_rules) ; +} + +rule test-header-isolation +{ + local all_rules = ; + local file ; + local headers_path = [ path.make $(BOOST_ROOT)/libs/$(self)/include ] ; + for file in [ path.glob-tree $(headers_path) : *.hpp ] + { + local rel_file = [ path.relative-to $(headers_path) $(file) ] ; + # Note: The test name starts with '~' in order to group these tests in the test report table, preferably at the end. + # All '/' are replaced with '-' because apparently test scripts have a problem with test names containing slashes. + local test_name = [ regex.replace $(rel_file) "/" "-" ] ; + local decl_test_name = ~hdr-decl-$(test_name) ; + # ECHO $(rel_file) ; + all_rules += [ compile compile/decl_header.cpp : "BOOST_TEST_HEADER=$(rel_file)" $(file) : $(decl_test_name) ] ; + } + + # ECHO All rules: $(all_rules) ; + return $(all_rules) ; +} + test-suite logic : + [ test-expected-failures ] + [ test-header-isolation ] [ run tribool_test.cpp ] [ run tribool_rename_test.cpp ] [ run tribool_io_test.cpp ] ; - - \ No newline at end of file diff --git a/test/compile-fail/implicit.cpp b/test/compile-fail/implicit.cpp new file mode 100644 index 0000000..ba56bfb --- /dev/null +++ b/test/compile-fail/implicit.cpp @@ -0,0 +1,23 @@ +// Copyright 2018 James E. King III. Use, modification and +// distribution is subject to 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) + +#include + +int main(int, char*[]) +{ + using boost::logic::indeterminate; + using boost::logic::tribool; + + tribool i(indeterminate); + +#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) + bool b = i; // expect to see: no viable conversion from 'boost::logic::tribool' to 'bool' + return (int)b; +#else +#error in c++03 explicit conversions are allowed +#endif + // NOTREACHED + return 0; +} diff --git a/test/compile-fail/implicit_int_1.cpp b/test/compile-fail/implicit_int_1.cpp new file mode 100644 index 0000000..4e88955 --- /dev/null +++ b/test/compile-fail/implicit_int_1.cpp @@ -0,0 +1,16 @@ +// Copyright 2018 James E. King III. Use, modification and +// distribution is subject to 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) + +#include + +int main(int, char*[]) +{ + using boost::logic::indeterminate; + using boost::logic::tribool; + + tribool i(indeterminate); + + return i; // expect to see: error: no viable conversion from returned value of type 'boost::logic::tribool' to function return type 'int' +} diff --git a/test/compile-fail/implicit_int_2.cpp b/test/compile-fail/implicit_int_2.cpp new file mode 100644 index 0000000..1401caa --- /dev/null +++ b/test/compile-fail/implicit_int_2.cpp @@ -0,0 +1,16 @@ +// Copyright 2018 James E. King III. Use, modification and +// distribution is subject to 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) + +#include + +int main(int, char*[]) +{ + using boost::logic::indeterminate; + using boost::logic::tribool; + + tribool i(indeterminate); + + return i + 1; // expect to see: error: invalid operands to binary expression ('boost::logic::tribool' and 'int') +} diff --git a/test/compile-fail/implicit_int_3.cpp b/test/compile-fail/implicit_int_3.cpp new file mode 100644 index 0000000..b6548c5 --- /dev/null +++ b/test/compile-fail/implicit_int_3.cpp @@ -0,0 +1,16 @@ +// Copyright 2018 James E. King III. Use, modification and +// distribution is subject to 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) + +#include + +int main(int, char*[]) +{ + using boost::logic::indeterminate; + using boost::logic::tribool; + + tribool i(indeterminate); + + return i << 1; // expect to see: error: invalid operands to binary expression ('boost::logic::tribool' and 'int') +} diff --git a/test/compile-fail/operator_less_1.cpp b/test/compile-fail/operator_less_1.cpp new file mode 100644 index 0000000..31be7ae --- /dev/null +++ b/test/compile-fail/operator_less_1.cpp @@ -0,0 +1,16 @@ +// Copyright 2018 James E. King III. Use, modification and +// distribution is subject to 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) + +#include + +int main(int, char*[]) +{ + using boost::logic::tribool; + + tribool f; // false + tribool t(true); // true + + return f < t; // expect to see: error: invalid operands to binary expression ('boost::logic::tribool' and 'boost::logic::tribool') +} diff --git a/test/compile-fail/operator_less_2.cpp b/test/compile-fail/operator_less_2.cpp new file mode 100644 index 0000000..53fc359 --- /dev/null +++ b/test/compile-fail/operator_less_2.cpp @@ -0,0 +1,15 @@ +// Copyright 2018 James E. King III. Use, modification and +// distribution is subject to 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) + +#include + +int main(int, char*[]) +{ + using boost::logic::tribool; + + tribool t(true); + + return t < 1; // expect to see: error: invalid operands to binary expression ('boost::logic::tribool' and 'int') +} diff --git a/test/compile/decl_header.cpp b/test/compile/decl_header.cpp new file mode 100644 index 0000000..2a28626 --- /dev/null +++ b/test/compile/decl_header.cpp @@ -0,0 +1,24 @@ +/* + * Copyright Andrey Semashev 2015. + * 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 decl_header.cpp + * \author Andrey Semashev + * \date 21.06.2015 + * + * \brief This file contains a test boilerplate for checking that every + * public header is self-contained and does not have any missing + * #includes. + */ + +#define BOOST_TEST_INCLUDE_HEADER() + +#include BOOST_TEST_INCLUDE_HEADER() + +int main(int, char*[]) +{ + return 0; +} diff --git a/test/tribool_test.cpp b/test/tribool_test.cpp index 77475d9..3781e37 100644 --- a/test/tribool_test.cpp +++ b/test/tribool_test.cpp @@ -3,7 +3,7 @@ // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #include #include @@ -16,6 +16,19 @@ int test_main(int, char*[]) tribool y(true); // true tribool z(indeterminate); // indeterminate +#if defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) + // c++03 allows for implicit conversion to bool + // c++11 uses an explicit conversion operator so this would not compile + // and that is tested in the compile-fail/implicit.cpp file + // so we check the conversion to ensure it is sane + bool bx = x; + BOOST_CHECK(bx == false); + bool by = y; + BOOST_CHECK(by == true); + bool bz = z; + BOOST_CHECK(bz == false); +#endif + BOOST_CHECK(!x); BOOST_CHECK(x == false); BOOST_CHECK(false == x); @@ -115,7 +128,7 @@ int test_main(int, char*[]) BOOST_CHECK(false); } -#ifndef BOOST_NO_CXX11_CONSTEXPR +#if !defined(BOOST_NO_CXX11_CONSTEXPR) constexpr bool res_ors = indeterminate(false || tribool(false) || false || indeterminate); // true BOOST_CHECK(res_ors); char array_ors[res_ors ? 2 : 3]; @@ -127,9 +140,13 @@ int test_main(int, char*[]) BOOST_CHECK(sizeof(array_ands) / sizeof(char) == 3); constexpr bool res_safe_bool = static_cast( tribool(true) ); - boost::ignore_unused(res_safe_bool); - constexpr tribool xxx = (tribool(true) || tribool(indeterminate)); - static_assert(xxx, "Must be true!"); + BOOST_STATIC_ASSERT(res_safe_bool); + +// gcc 4.6 chokes on the xxx assignment +# if !BOOST_WORKAROUND(BOOST_GCC, < 40700) + constexpr tribool xxx = (tribool(true) || tribool(indeterminate)); + BOOST_STATIC_ASSERT(xxx); +# endif #endif std::cout << "no errors detected\n";