diff --git a/include/boost/test/data/size.hpp b/include/boost/test/data/size.hpp index 3e9ba96795..daa63ea51a 100644 --- a/include/boost/test/data/size.hpp +++ b/include/boost/test/data/size.hpp @@ -30,7 +30,7 @@ namespace data { // ************** size_t ************** // // ************************************************************************** // -//! Utility for handling the size of a datasets +//! Utility for handling the size of a dataset class size_t { struct dummy { void nonnull() {} }; typedef void (dummy::*safe_bool)(); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index ddf6ad5ac3..20ae7c7ea9 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -150,6 +150,7 @@ test-suite "framework-ts" [ boost.test-self-test run : framework-ts : decorators-datatestcase-test : : : : : : $(requirements_datasets) ] [ compile-fail framework-ts/master-test-suite-non-copyable-test.cpp ../build//included ] [ boost.test-self-test run : framework-ts : log-count-skipped-test : included : baseline-outputs/log-count-skipped-tests.pattern ] + [ boost.test-self-test run : framework-ts : dataset-size ] # ticket 13371: "Use-after-free with --log_sink=file" # this single check is not enough as we should check for various command line options: we make extensive diff --git a/test/framework-ts/dataset-size.cpp b/test/framework-ts/dataset-size.cpp new file mode 100644 index 0000000000..647ec58494 --- /dev/null +++ b/test/framework-ts/dataset-size.cpp @@ -0,0 +1,251 @@ +// (C) Copyright Alexander Grund 2025. +// 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) + +#define BOOST_TEST_MODULE dataset size class +#include + +#include +#include + +namespace data = boost::unit_test::data; + +BOOST_AUTO_TEST_CASE(test_constructor) +{ + data::size_t sz0; + BOOST_TEST(!sz0.is_inf()); + BOOST_TEST(sz0.value() == 0u); + BOOST_TEST(!sz0); + + data::size_t sz2 = sz0; + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + BOOST_TEST(!sz2); + + data::size_t sz1(42); + BOOST_TEST(!sz1.is_inf()); + BOOST_TEST(sz1.value() == 42u); + BOOST_TEST(!!sz1); + + data::size_t sz3 = sz1; + BOOST_TEST(!sz3.is_inf()); + BOOST_TEST(sz3.value() == 42u); + BOOST_TEST(!!sz3); + + data::size_t sz4(true); + BOOST_TEST(sz4.is_inf()); + BOOST_TEST(sz4.value() == 0u); + BOOST_TEST(!!sz4); + + data::size_t sz5(false); + BOOST_TEST(sz5.is_inf()); + BOOST_TEST(sz5.value() == 0u); + BOOST_TEST(!!sz5); + + sz2 = sz5; + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + BOOST_TEST(!!sz2); + + sz2 = sz1; + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 42u); + BOOST_TEST(!!sz2); +} + +BOOST_AUTO_TEST_CASE(test_unary_ops) +{ + data::size_t sz(100); + + data::size_t sz2 = ++sz; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 101u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 101u); + + sz2 = sz++; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 102u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 101u); + + sz2 = --sz; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 101u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 101u); + + sz2 = sz--; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 100u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 101u); + + // Over- and underflow + BOOST_CONSTEXPR_OR_CONST std::size_t maxVal = (std::numeric_limits::max)(); + sz = maxVal; + sz2 = ++sz; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + sz = maxVal; + sz2 = sz++; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 0); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == maxVal); + + sz = 0; + sz2 = --sz; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == maxVal); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == maxVal); + + sz = 0; + sz2 = sz--; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == maxVal); + BOOST_TEST(!sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + //____________________________________________________________________________// + sz = data::BOOST_TEST_DS_INFINITE_SIZE; + sz2 = ++sz; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + sz2 = sz++; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + sz2 = --sz; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); + + sz2 = sz--; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + BOOST_TEST(sz2.is_inf()); + BOOST_TEST(sz2.value() == 0u); +} + +BOOST_AUTO_TEST_CASE(test_binary_inc) +{ + data::size_t sz(100); + + sz += 5; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 105u); + + sz += data::size_t(5); + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 110u); + + sz += data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + //____________________________________________________________________________// + sz = data::BOOST_TEST_DS_INFINITE_SIZE; + + sz += 5; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz += data::size_t(5); + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz += data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + //____________________________________________________________________________// + data::size_t sz2(100); + + sz = sz2 + 5; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 105u); + + sz = sz2 + data::size_t(5); + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 105u); + + sz = sz2 + data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + //____________________________________________________________________________// + sz2 = data::BOOST_TEST_DS_INFINITE_SIZE; + + sz = sz2 + 5; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz = sz2 + data::size_t(5); + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz = sz2 + data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); +} + +BOOST_AUTO_TEST_CASE(test_binary_dec) +{ + data::size_t sz(100); + + sz -= 5; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 95u); + + sz -= data::size_t(5); + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 90u); + + sz -= data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 90u); + + //____________________________________________________________________________// + sz = data::BOOST_TEST_DS_INFINITE_SIZE; + + sz -= 5; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz -= data::size_t(5); + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz -= data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + BOOST_CONSTEXPR_OR_CONST std::size_t maxVal = (std::numeric_limits::max)(); + // Underflow is avoided for data::size_t values + sz = 1; + sz -= 5; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == maxVal - 5u + 2u); + + sz = 1; + sz -= data::size_t(5); + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 0u); + + sz = 1; + sz -= data::BOOST_TEST_DS_INFINITE_SIZE; + BOOST_TEST(!sz.is_inf()); + BOOST_TEST(sz.value() == 1u); +} \ No newline at end of file