diff --git a/doc/todo.qbk b/doc/todo.qbk index aa1c845..ea50d20 100644 --- a/doc/todo.qbk +++ b/doc/todo.qbk @@ -1,5 +1,5 @@ [/ -Copyright 2014 Rene Rivera +Copyright 2014-2017 Rene Rivera 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) @@ -8,6 +8,5 @@ http://www.boost.org/LICENSE_1_0.txt) [section To Do] * Improve reference documentation. -* Provide BOOST_WORKAROUND style macros for public use. [endsect] diff --git a/include/boost/predef/other/workaround.h b/include/boost/predef/other/workaround.h new file mode 100644 index 0000000..7167a18 --- /dev/null +++ b/include/boost/predef/other/workaround.h @@ -0,0 +1,87 @@ +/* +Copyright Rene Rivera 2017 +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) +*/ + +#ifndef BOOST_PREDEF_WORKAROUND_H +#define BOOST_PREDEF_WORKAROUND_H + +/*` +[heading `BOOST_PREDEF_WORKAROUND`] + +`` +BOOST_PREDEF_WORKAROUND(symbol,comp,major,minor,patch) +`` + +Usage: + +`` +#if BOOST_PREDEF_WORKAROUND(BOOST_COMP_CLANG,<,3,0,0) + // Workaround for old clang compilers.. +#endif +`` + +Defines a comparison against two version numbers that depends on the definion +of `BOOST_STRICT_CONFIG`. When `BOOST_STRICT_CONFIG` is defined this will expand +to a value convertible to `false`. Which has the effect of disabling all code +conditionally guarded by `BOOST_PREDEF_WORKAROUND`. When `BOOST_STRICT_CONFIG` +is undefine this expand to test the given `symbol` version value with the +`comp` comparison against `BOOST_VERSION_NUMBER(major,minor,patch)`. +*/ +#ifdef BOOST_STRICT_CONFIG +# define BOOST_PREDEF_WORKAROUND(symbol, comp, major, minor, patch) (0) +#else +# include +# define BOOST_PREDEF_WORKAROUND(symbol, comp, major, minor, patch) \ + ( (symbol) != (0) ) && \ + ( (symbol) comp (BOOST_VERSION_NUMBER( (major) , (minor) , (patch) )) ) +#endif + +/*` +[heading `BOOST_PREDEF_TESTED_AT`] + +`` +BOOST_PREDEF_TESTED_AT(symbol,major,minor,patch) +`` + +Usage: + +`` +#if BOOST_PREDEF_TESTED_AT(BOOST_COMP_CLANG,3,5,0) + // Needed for clang, and last checked for 3.5.0. +#endif +`` + +Defines a comparison against two version numbers that depends on the definion +of `BOOST_STRICT_CONFIG` and `BOOST_DETECT_OUTDATED_WORKAROUNDS`. +When `BOOST_STRICT_CONFIG` is defined this will expand to a value convertible +to `false`. Which has the effect of disabling all code +conditionally guarded by `BOOST_PREDEF_TESTED_AT`. When `BOOST_STRICT_CONFIG` +is undefined this expand to either: + +* A value convertible to `true` when `BOOST_DETECT_OUTDATED_WORKAROUNDS` is not + defined. +* A value convertible `true` when the expansion of + `BOOST_PREDEF_WORKAROUND(symbol, <=, major, minor, patch)` is `true` and + `BOOST_DETECT_OUTDATED_WORKAROUNDS` is defined. +* A compile error when the expansion of + `BOOST_PREDEF_WORKAROUND(symbol, >, major, minor, patch)` is true and + `BOOST_DETECT_OUTDATED_WORKAROUNDS` is defined. +*/ +#ifdef BOOST_STRICT_CONFIG +# define BOOST_PREDEF_TESTED_AT(symbol, major, minor, patch) (0) +#else +# ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS +# define BOOST_PREDEF_TESTED_AT(symbol, major, minor, patch) ( \ + BOOST_PREDEF_WORKAROUND(symbol, <=, major, minor, patch) \ + ? 1 \ + : (1%0) ) +# else +# define BOOST_PREDEF_TESTED_AT(symbol, major, minor, patch) \ + ( (symbol) >= BOOST_VERSION_NUMBER_AVAILABLE ) +# endif +#endif + +#endif diff --git a/test/build.jam b/test/build.jam index 74c658c..43bf007 100755 --- a/test/build.jam +++ b/test/build.jam @@ -59,6 +59,10 @@ test-suite predef : [ compile macos_vs_bsd.c : [ predef-require "BOOST_OS_MACOS" : cpp ] ] [ run check_value.cpp : : : always_show_run_output [ predef-check "BOOST_COMP_CLANG > 0.0.0" "BOOST_OS_LINUX == 0" : : -DCHECK_VALUE=true ] ] + [ run workaround.cpp ] + [ compile workaround_strict_config.cpp ] + [ run tested_at.cpp ] + [ compile-fail tested_at_outdated.cpp : always_show_run_output ] ; # Minimal testing done for predef for CI. Since diff --git a/test/tested_at.cpp b/test/tested_at.cpp new file mode 100644 index 0000000..2c4816e --- /dev/null +++ b/test/tested_at.cpp @@ -0,0 +1,62 @@ +/* +Copyright Rene Rivera 2011-2017 +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) +*/ +#include +#include +#include +#include +#include +#include + +namespace +{ + struct test_info + { + std::string value; + bool passed; + + test_info(std::string const & v, bool p) : value(v), passed(p) {} + test_info(test_info const & o) : value(o.value), passed(o.passed) {} + }; + + std::vector test_results; +} + +#define PREDEF_CHECK(X) test_results.push_back(test_info(#X,(X))) + +void test_BOOST_PREDEF_TESTED_AT() +{ + PREDEF_CHECK(BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(15,15,15),0xF,0xF,0xF)); + PREDEF_CHECK(BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(1,0,0),1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(0,9,0),1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(2,0,0),1,0,0)); + PREDEF_CHECK(!BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER_NOT_AVAILABLE,1,0,0)); +} + +int main() +{ + test_BOOST_PREDEF_TESTED_AT(); + + unsigned fail_count = 0; + std::vector::iterator i = test_results.begin(); + std::vector::iterator e = test_results.end(); + for (; i != e; ++i) + { + std::cout + << (i->passed ? "[passed]" : "[failed]") + << " " << i->value + << std::endl; + fail_count += i->passed ? 0 : 1; + } + std::cout + << std::endl + << "TOTAL: " + << "passed " << (test_results.size()-fail_count) << ", " + << "failed " << (fail_count) << ", " + << "of " << (test_results.size()) + << std::endl; + return fail_count; +} diff --git a/test/tested_at_outdated.cpp b/test/tested_at_outdated.cpp new file mode 100644 index 0000000..534ebaf --- /dev/null +++ b/test/tested_at_outdated.cpp @@ -0,0 +1,18 @@ +/* +Copyright Rene Rivera 2011-2017 +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) +*/ +#include +#define BOOST_DETECT_OUTDATED_WORKAROUNDS +#include + +int main() +{ +#if BOOST_PREDEF_TESTED_AT(BOOST_VERSION_NUMBER(2,0,0),1,0,0) + return 1; +#else + return 0; +#endif +} diff --git a/test/workaround.cpp b/test/workaround.cpp new file mode 100644 index 0000000..368daea --- /dev/null +++ b/test/workaround.cpp @@ -0,0 +1,62 @@ +/* +Copyright Rene Rivera 2011-2017 +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) +*/ +#include +#include +#include +#include +#include +#include + +namespace +{ + struct test_info + { + std::string value; + bool passed; + + test_info(std::string const & v, bool p) : value(v), passed(p) {} + test_info(test_info const & o) : value(o.value), passed(o.passed) {} + }; + + std::vector test_results; +} + +#define PREDEF_CHECK(X) test_results.push_back(test_info(#X,(X))) + +void test_BOOST_PREDEF_WORKAROUND() +{ + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER(15,15,15),==,0xF,0xF,0xF)); + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER(0,9,0),<,1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER(0,9,0),!=,1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER_MIN,<,1,0,0)); + PREDEF_CHECK(BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER_MIN,>,0,0,0)); +} + +int main() +{ + test_BOOST_PREDEF_WORKAROUND(); + + unsigned fail_count = 0; + std::vector::iterator i = test_results.begin(); + std::vector::iterator e = test_results.end(); + for (; i != e; ++i) + { + std::cout + << (i->passed ? "[passed]" : "[failed]") + << " " << i->value + << std::endl; + fail_count += i->passed ? 0 : 1; + } + std::cout + << std::endl + << "TOTAL: " + << "passed " << (test_results.size()-fail_count) << ", " + << "failed " << (fail_count) << ", " + << "of " << (test_results.size()) + << std::endl; + return fail_count; +} diff --git a/test/workaround_strict_config.cpp b/test/workaround_strict_config.cpp new file mode 100644 index 0000000..df7b176 --- /dev/null +++ b/test/workaround_strict_config.cpp @@ -0,0 +1,17 @@ +/* +Copyright Rene Rivera 2011-2017 +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) +*/ +#include +#define BOOST_STRICT_CONFIG +#include + +int main() +{ +#if BOOST_PREDEF_WORKAROUND(BOOST_VERSION_NUMBER_AVAILABLE,==,0,0,1) + fail(); +#endif + return 0; +}