diff options
Diffstat (limited to 'src/boost/libs/any/test')
34 files changed, 1816 insertions, 0 deletions
diff --git a/src/boost/libs/any/test/Jamfile.v2 b/src/boost/libs/any/test/Jamfile.v2 new file mode 100644 index 000000000..c6ea16c51 --- /dev/null +++ b/src/boost/libs/any/test/Jamfile.v2 @@ -0,0 +1,50 @@ +# Copyright Vladimir Prus 2005. 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) +# +# For more information, see http://www.boost.org/libs/any +# + +import testing ; + +test-suite any : + [ run any_test.cpp ] + [ run any_test.cpp : : : <rtti>off <define>BOOST_NO_RTTI <define>BOOST_NO_TYPEID : any_test_no_rtti ] + [ run any_test_rv.cpp ] + [ run any_test_rv.cpp : : : <rtti>off <define>BOOST_NO_RTTI <define>BOOST_NO_TYPEID : any_test_rv_no_rtti ] + [ run any_test_mplif.cpp ] + [ compile-fail any_cast_cv_failed.cpp ] + [ compile-fail any_test_temporary_to_ref_failed.cpp ] + [ compile-fail any_test_cv_to_rv_failed.cpp ] + [ run basic_any_test.cpp ] + [ run basic_any_test.cpp : : : <rtti>off <define>BOOST_NO_RTTI <define>BOOST_NO_TYPEID : basic_any_test_no_rtti ] + [ run basic_any_test_rv.cpp ] + [ run basic_any_test_rv.cpp : : : <rtti>off <define>BOOST_NO_RTTI <define>BOOST_NO_TYPEID : basic_any_test_rv_no_rtti ] + [ run basic_any_test_mplif.cpp ] + [ run basic_any_test_large_object.cpp ] + [ run basic_any_test_small_object.cpp ] + [ compile-fail basic_any_cast_cv_failed.cpp ] + [ compile-fail basic_any_test_alignment_power_of_two_failed.cpp ] + [ compile-fail basic_any_test_cv_to_rv_failed.cpp ] + [ compile-fail basic_any_test_multiply_size_failed.cpp ] + [ compile-fail basic_any_test_size_alignment_zero_failed.cpp ] + [ compile-fail basic_any_test_size_less_alignment_failed.cpp ] + [ compile-fail basic_any_test_temporary_to_ref_failed.cpp ] + + [ compile-fail any_from_basic_any.cpp ] + [ compile-fail any_to_basic_any.cpp ] + [ compile-fail basic_any_from_any.cpp ] + [ compile-fail basic_any_to_any.cpp ] + [ compile-fail any_from_basic_any_rv.cpp ] + [ compile-fail any_to_basic_any_rv.cpp ] + [ compile-fail basic_any_from_any_rv.cpp ] + [ compile-fail basic_any_to_any_rv.cpp ] + + [ compile-fail basic_any_from_basic_any.cpp ] + [ compile-fail basic_any_to_basic_any.cpp ] + [ compile-fail basic_any_from_basic_any_rv.cpp ] + [ compile-fail basic_any_to_basic_any_rv.cpp ] + ; + + diff --git a/src/boost/libs/any/test/any_cast_cv_failed.cpp b/src/boost/libs/any/test/any_cast_cv_failed.cpp new file mode 100644 index 000000000..c07877cbc --- /dev/null +++ b/src/boost/libs/any/test/any_cast_cv_failed.cpp @@ -0,0 +1,14 @@ +// Copyright 2006 Alexander Nasonov. +// Copyright Antony Polukhin, 2013-2022. +// +// 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 <boost/any.hpp> + +int main() { + boost::any const a; + boost::any_cast<int&>(a); +} + diff --git a/src/boost/libs/any/test/any_from_basic_any.cpp b/src/boost/libs/any/test/any_from_basic_any.cpp new file mode 100644 index 000000000..801e7565f --- /dev/null +++ b/src/boost/libs/any/test/any_from_basic_any.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<> bany = 42; + boost::any value = bany; +} + diff --git a/src/boost/libs/any/test/any_from_basic_any_rv.cpp b/src/boost/libs/any/test/any_from_basic_any_rv.cpp new file mode 100644 index 000000000..e117bb15d --- /dev/null +++ b/src/boost/libs/any/test/any_from_basic_any_rv.cpp @@ -0,0 +1,13 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::any value = boost::anys::basic_any<>(42); +} + diff --git a/src/boost/libs/any/test/any_test.cpp b/src/boost/libs/any/test/any_test.cpp new file mode 100644 index 000000000..d722916de --- /dev/null +++ b/src/boost/libs/any/test/any_test.cpp @@ -0,0 +1,65 @@ +// Copyright Kevlin Henney, 2000, 2001. All rights reserved. +// Copyright Antony Polukhin, 2013-2022. +// +// 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) + +// what: unit tests for variant type boost::any +// who: contributed by Kevlin Henney +// when: July 2001, 2013, 2014 +// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 + +#include <boost/any.hpp> + +#include "basic_test.hpp" + +static const std::string& returning_string1() +{ + static const std::string ret("foo"); + return ret; +} + +static std::string returning_string2() +{ + static const std::string ret("foo"); + return ret; +} + +static void test_with_func() +{ + std::string s; + s = boost::any_cast<std::string>(returning_string1()); + s = boost::any_cast<const std::string&>(returning_string1()); + + s = boost::any_cast<std::string>(returning_string2()); + s = boost::any_cast<const std::string&>(returning_string2()); + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(__INTEL_COMPILER) && !defined(__ICL) && (!defined(_MSC_VER) || _MSC_VER != 1600) + // Intel compiler thinks that it must choose the `any_cast(const any&)` function + // instead of the `any_cast(const any&&)`. + // Bug was not reported because of missing premier support account + annoying + // registrations requirements. + + // MSVC-10 had a bug: + // + // any.hpp(291) : error C2440: 'return' : cannot convert. + // Conversion loses qualifiers + // any_test.cpp(304) : see reference to function template instantiation + // + // This issue was fixed in MSVC-11. + + s = boost::any_cast<std::string&&>(returning_string1()); +#endif + + s = boost::any_cast<std::string&&>(returning_string2()); +#endif +} + +int main() { + test_with_func(); + + return any_tests::basic_tests<boost::any>::run_tests(); +} + diff --git a/src/boost/libs/any/test/any_test_cv_to_rv_failed.cpp b/src/boost/libs/any/test/any_test_cv_to_rv_failed.cpp new file mode 100644 index 000000000..9bfd48124 --- /dev/null +++ b/src/boost/libs/any/test/any_test_cv_to_rv_failed.cpp @@ -0,0 +1,39 @@ +// Unit test for boost::any. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Antony Polukhin, 2013-2022. +// +// 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 <cstdlib> +#include <string> +#include <utility> + +#include <boost/any.hpp> +#include "test.hpp" +#include <boost/move/move.hpp> + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +int main() +{ + BOOST_STATIC_ASSERT(false); + return EXIT_SUCCESS; +} + +#else + + +int main() +{ + boost::any const cvalue(10); + int i = boost::any_cast<int&&>(cvalue); + (void)i; + return EXIT_SUCCESS; +} + +#endif + diff --git a/src/boost/libs/any/test/any_test_mplif.cpp b/src/boost/libs/any/test/any_test_mplif.cpp new file mode 100644 index 000000000..cd883cb13 --- /dev/null +++ b/src/boost/libs/any/test/any_test_mplif.cpp @@ -0,0 +1,19 @@ +// Copyright Antony Polukhin, 2017-2022. +// +// 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) + +// This tests the issue from https://svn.boost.org/trac/boost/ticket/12052 + +#include <iostream> +#include <boost/any.hpp> + +int main() { + boost::any a = 1; + std::cout << boost::any_cast<int>(a) << '\n'; + a = 3.14; + std::cout << boost::any_cast<double>(a) << '\n'; + a = true; + std::cout << std::boolalpha << boost::any_cast<bool>(a) << '\n'; +} diff --git a/src/boost/libs/any/test/any_test_rv.cpp b/src/boost/libs/any/test/any_test_rv.cpp new file mode 100644 index 000000000..436c4f94b --- /dev/null +++ b/src/boost/libs/any/test/any_test_rv.cpp @@ -0,0 +1,29 @@ +// Unit test for boost::any. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Antony Polukhin, 2013-2022. +// +// 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 <boost/any.hpp> + +#include "move_test.hpp" + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +int main() +{ + return EXIT_SUCCESS; +} + +#else + +int main() { + return any_tests::move_tests<boost::any>::run_tests(); +} + +#endif + diff --git a/src/boost/libs/any/test/any_test_temporary_to_ref_failed.cpp b/src/boost/libs/any/test/any_test_temporary_to_ref_failed.cpp new file mode 100644 index 000000000..a4ef83bf7 --- /dev/null +++ b/src/boost/libs/any/test/any_test_temporary_to_ref_failed.cpp @@ -0,0 +1,38 @@ +// Unit test for boost::any. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Antony Polukhin, 2013-2022. +// +// 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 <cstdlib> +#include <string> +#include <utility> + +#include <boost/any.hpp> +#include "test.hpp" +#include <boost/move/move.hpp> + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +int main() +{ + BOOST_STATIC_ASSERT(false); + return EXIT_SUCCESS; +} + +#else + + +int main() +{ + int i = boost::any_cast<int&>(10); + (void)i; + return EXIT_SUCCESS; +} + +#endif + diff --git a/src/boost/libs/any/test/any_to_basic_any.cpp b/src/boost/libs/any/test/any_to_basic_any.cpp new file mode 100644 index 000000000..f297414d0 --- /dev/null +++ b/src/boost/libs/any/test/any_to_basic_any.cpp @@ -0,0 +1,15 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::any value = 10; + boost::anys::basic_any<> bany; + bany = value; +} + diff --git a/src/boost/libs/any/test/any_to_basic_any_rv.cpp b/src/boost/libs/any/test/any_to_basic_any_rv.cpp new file mode 100644 index 000000000..8693c07c0 --- /dev/null +++ b/src/boost/libs/any/test/any_to_basic_any_rv.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<> bany; + bany = boost::any(10); +} + diff --git a/src/boost/libs/any/test/basic_any_cast_cv_failed.cpp b/src/boost/libs/any/test/basic_any_cast_cv_failed.cpp new file mode 100644 index 000000000..eaccae0df --- /dev/null +++ b/src/boost/libs/any/test/basic_any_cast_cv_failed.cpp @@ -0,0 +1,15 @@ +// Copyright 2006 Alexander Nasonov. +// Copyright Antony Polukhin, 2013-2022. +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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 <boost/any/basic_any.hpp> + +int main() { + boost::anys::basic_any<> const a; + boost::any_cast<int&>(a); +} + diff --git a/src/boost/libs/any/test/basic_any_from_any.cpp b/src/boost/libs/any/test/basic_any_from_any.cpp new file mode 100644 index 000000000..274e3839a --- /dev/null +++ b/src/boost/libs/any/test/basic_any_from_any.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::any value = 42; + boost::anys::basic_any<256, 16> bany = value; +} + diff --git a/src/boost/libs/any/test/basic_any_from_any_rv.cpp b/src/boost/libs/any/test/basic_any_from_any_rv.cpp new file mode 100644 index 000000000..49fa06dca --- /dev/null +++ b/src/boost/libs/any/test/basic_any_from_any_rv.cpp @@ -0,0 +1,13 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<256, 16> bany = boost::any(42); +} + diff --git a/src/boost/libs/any/test/basic_any_from_basic_any.cpp b/src/boost/libs/any/test/basic_any_from_basic_any.cpp new file mode 100644 index 000000000..607b56da3 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_from_basic_any.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<256, 32> another(10); + boost::anys::basic_any<> bany = another; +} + diff --git a/src/boost/libs/any/test/basic_any_from_basic_any_rv.cpp b/src/boost/libs/any/test/basic_any_from_basic_any_rv.cpp new file mode 100644 index 000000000..3b2a7f832 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_from_basic_any_rv.cpp @@ -0,0 +1,13 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<> bany = boost::anys::basic_any<256>(10); +} + diff --git a/src/boost/libs/any/test/basic_any_test.cpp b/src/boost/libs/any/test/basic_any_test.cpp new file mode 100644 index 000000000..57d4db5b4 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test.cpp @@ -0,0 +1,24 @@ +// Copyright Kevlin Henney, 2000, 2001. All rights reserved. +// Copyright Antony Polukhin, 2013-2022. +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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 "boost/any/basic_any.hpp" +#include "basic_test.hpp" + +int main() { + const int res1 = any_tests::basic_tests<boost::anys::basic_any<> >::run_tests(); + if (res1) return 1; + + const int res2 = any_tests::basic_tests<boost::anys::basic_any<256, 8> >::run_tests(); + if (res2) return 2; + + const int res3 = any_tests::basic_tests<boost::anys::basic_any<1, 1> >::run_tests(); + if (res3) return 3; + + const int res4 = any_tests::basic_tests<boost::anys::basic_any<64, 8> >::run_tests(); + if (res4) return 4; +} diff --git a/src/boost/libs/any/test/basic_any_test_alignment_power_of_two_failed.cpp b/src/boost/libs/any/test/basic_any_test_alignment_power_of_two_failed.cpp new file mode 100644 index 000000000..f4df460f9 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_alignment_power_of_two_failed.cpp @@ -0,0 +1,12 @@ +// Copyright Ruslan Arutyunyan, 2019-2021. +// Copyright Antony Polukhin, 2021-2022. +// +// 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 <boost/any/basic_any.hpp> + +int main() { + boost::anys::basic_any<10, 5> a; +} diff --git a/src/boost/libs/any/test/basic_any_test_cv_to_rv_failed.cpp b/src/boost/libs/any/test/basic_any_test_cv_to_rv_failed.cpp new file mode 100644 index 000000000..e35bca0f6 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_cv_to_rv_failed.cpp @@ -0,0 +1,40 @@ +// Unit test for boost::any. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Antony Polukhin, 2013-2019. +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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 <cstdlib> +#include <string> +#include <utility> + +#include <boost/any/basic_any.hpp> +#include "test.hpp" +#include <boost/move/move.hpp> + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +int main() +{ + BOOST_STATIC_ASSERT(false); + return EXIT_SUCCESS; +} + +#else + + +int main() +{ + boost::anys::basic_any<> const cvalue(10); + int i = boost::any_cast<int&&>(cvalue); + (void)i; + return EXIT_SUCCESS; +} + +#endif + diff --git a/src/boost/libs/any/test/basic_any_test_large_object.cpp b/src/boost/libs/any/test/basic_any_test_large_object.cpp new file mode 100644 index 000000000..bfeaa7805 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_large_object.cpp @@ -0,0 +1,62 @@ +// Copyright Ruslan Arutyunyan, 2019-2021. +// Copyright Antony Polukhin, 2021-2022. +// +// 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 <boost/any/basic_any.hpp> + +#include <boost/core/lightweight_test.hpp> + +#include <cassert> + +static int move_ctors_count = 0; +static int destructors_count = 0; + +struct A { + char a[32]; + + A() {} + A(const A&) {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + A(A&&) BOOST_NOEXCEPT { + ++move_ctors_count; + } +#endif + + ~A() { + ++destructors_count; + } +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template <class T> + T&& portable_move(T& value) { + return std::move(value); + } +#else + template <class T> + T& portable_move(T& value) { + return value; + } +#endif + +int main() { + { + A a; + boost::anys::basic_any<24, 8> any1(a); + boost::anys::basic_any<24, 8> any2(portable_move(any1)); + boost::anys::basic_any<24, 8> any3(portable_move(any2)); + BOOST_TEST_EQ(move_ctors_count, 0); + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + BOOST_TEST_EQ(destructors_count, 2); +#else + BOOST_TEST_EQ(destructors_count, 4); +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/any/test/basic_any_test_mplif.cpp b/src/boost/libs/any/test/basic_any_test_mplif.cpp new file mode 100644 index 000000000..67acedce4 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_mplif.cpp @@ -0,0 +1,20 @@ +// Copyright Antony Polukhin, 2017-2022. +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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) + +// This tests the issue from https://svn.boost.org/trac/boost/ticket/12052 + +#include <iostream> +#include <boost/any/basic_any.hpp> + +int main() { + boost::anys::basic_any<> a = 1; + std::cout << boost::any_cast<int>(a) << '\n'; + a = 3.14; + std::cout << boost::any_cast<double>(a) << '\n'; + a = true; + std::cout << std::boolalpha << boost::any_cast<bool>(a) << '\n'; +} diff --git a/src/boost/libs/any/test/basic_any_test_multiply_size_failed.cpp b/src/boost/libs/any/test/basic_any_test_multiply_size_failed.cpp new file mode 100644 index 000000000..7b826ff86 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_multiply_size_failed.cpp @@ -0,0 +1,16 @@ +// Unit test for boost::any. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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 <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<23, 8> a; +} diff --git a/src/boost/libs/any/test/basic_any_test_rv.cpp b/src/boost/libs/any/test/basic_any_test_rv.cpp new file mode 100644 index 000000000..fb34e11a9 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_rv.cpp @@ -0,0 +1,39 @@ +// Unit test for boost::basic_any<>. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Antony Polukhin, 2013-2022. +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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 <boost/any/basic_any.hpp> + +#include "move_test.hpp" + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +int main() +{ + return EXIT_SUCCESS; +} + +#else + +int main() { + const int res1 = any_tests::move_tests<boost::anys::basic_any<> >::run_tests(); + if (res1) return 1; + + const int res2 = any_tests::move_tests<boost::anys::basic_any<256, 8> >::run_tests(); + if (res2) return 2; + + const int res3 = any_tests::move_tests<boost::anys::basic_any<1, 1> >::run_tests(); + if (res3) return 3; + + const int res4 = any_tests::move_tests<boost::anys::basic_any<64, 8> >::run_tests(); + if (res4) return 4; +} + +#endif diff --git a/src/boost/libs/any/test/basic_any_test_size_alignment_zero_failed.cpp b/src/boost/libs/any/test/basic_any_test_size_alignment_zero_failed.cpp new file mode 100644 index 000000000..6bd0627ac --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_size_alignment_zero_failed.cpp @@ -0,0 +1,16 @@ +// Unit test for boost::any. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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 <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<0, 0> a; +} diff --git a/src/boost/libs/any/test/basic_any_test_size_less_alignment_failed.cpp b/src/boost/libs/any/test/basic_any_test_size_less_alignment_failed.cpp new file mode 100644 index 000000000..01a1e5fe9 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_size_less_alignment_failed.cpp @@ -0,0 +1,16 @@ +// Unit test for boost::any. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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 <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<1, 4> a; +} diff --git a/src/boost/libs/any/test/basic_any_test_small_object.cpp b/src/boost/libs/any/test/basic_any_test_small_object.cpp new file mode 100644 index 000000000..e4498a4bc --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_small_object.cpp @@ -0,0 +1,71 @@ +// Copyright Ruslan Arutyunyan, 2019-2021. +// Copyright Antony Polukhin, 2021-2022. +// +// 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 <boost/any/basic_any.hpp> + +#include <boost/core/lightweight_test.hpp> + +#include <cassert> + +static int move_ctors_count = 0; +static int destructors_count = 0; + +struct A { + char a[24]; + + A() {} + A(const A&) {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + A(A&&) BOOST_NOEXCEPT { + ++move_ctors_count; + } +#endif + + ~A() { + ++destructors_count; + } +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template <class T> + T&& portable_move(T& value) { + return std::move(value); + } +#else + template <class T> + T& portable_move(T& value) { + return value; + } +#endif + + +int main() { +#if !defined(__GNUC__) || __GNUC__ > 4 + { + A a; + boost::anys::basic_any<24, 8> any1(a); + boost::anys::basic_any<24, 8> any2(portable_move(any1)); + boost::anys::basic_any<24, 8> any3(portable_move(any2)); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_NOEXCEPT) + BOOST_TEST_EQ(move_ctors_count, 2); +#else + BOOST_TEST_EQ(move_ctors_count, 0); +#endif + } + +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + // The move constructor is not marked with noexcept, so the large_manager is used. + // Moving large_manager data is just swapping pointers without calling destructors. + BOOST_TEST_EQ(destructors_count, 2); +#else + BOOST_TEST_EQ(destructors_count, 4); +#endif + +#endif // #if !defined(__GNUC__) || __GNUC__ > 4 + return boost::report_errors(); +} diff --git a/src/boost/libs/any/test/basic_any_test_temporary_to_ref_failed.cpp b/src/boost/libs/any/test/basic_any_test_temporary_to_ref_failed.cpp new file mode 100644 index 000000000..ac7248016 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_test_temporary_to_ref_failed.cpp @@ -0,0 +1,39 @@ +// Unit test for boost::any. +// +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Antony Polukhin, 2013-2019. +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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 <cstdlib> +#include <string> +#include <utility> + +#include <boost/any/basic_any.hpp> +#include "test.hpp" +#include <boost/move/move.hpp> + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +int main() +{ + BOOST_STATIC_ASSERT(false); + return EXIT_SUCCESS; +} + +#else + + +int main() +{ + int i = boost::any_cast<int&>(boost::anys::basic_any<>(10)); + (void)i; + return EXIT_SUCCESS; +} + +#endif + diff --git a/src/boost/libs/any/test/basic_any_to_any.cpp b/src/boost/libs/any/test/basic_any_to_any.cpp new file mode 100644 index 000000000..f04fec4da --- /dev/null +++ b/src/boost/libs/any/test/basic_any_to_any.cpp @@ -0,0 +1,15 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<256, 16> bany = 10; + boost::any value; + value = bany; +} + diff --git a/src/boost/libs/any/test/basic_any_to_any_rv.cpp b/src/boost/libs/any/test/basic_any_to_any_rv.cpp new file mode 100644 index 000000000..dfd060506 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_to_any_rv.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::any value; + value = boost::anys::basic_any<256, 16>(10); +} + diff --git a/src/boost/libs/any/test/basic_any_to_basic_any.cpp b/src/boost/libs/any/test/basic_any_to_basic_any.cpp new file mode 100644 index 000000000..46ce07835 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_to_basic_any.cpp @@ -0,0 +1,15 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<> bany; + boost::anys::basic_any<256, 32> another(10); + bany = another; +} + diff --git a/src/boost/libs/any/test/basic_any_to_basic_any_rv.cpp b/src/boost/libs/any/test/basic_any_to_basic_any_rv.cpp new file mode 100644 index 000000000..24dc13113 --- /dev/null +++ b/src/boost/libs/any/test/basic_any_to_basic_any_rv.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2021-2022 Antony Polukhin +// +// 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 <boost/any.hpp> +#include <boost/any/basic_any.hpp> + +int main() +{ + boost::anys::basic_any<> bany; + bany = boost::anys::basic_any<256, 32>(10); +} + diff --git a/src/boost/libs/any/test/basic_test.hpp b/src/boost/libs/any/test/basic_test.hpp new file mode 100644 index 000000000..8495d201d --- /dev/null +++ b/src/boost/libs/any/test/basic_test.hpp @@ -0,0 +1,400 @@ +// Copyright Kevlin Henney, 2000, 2001. All rights reserved. +// Copyright Antony Polukhin, 2013-2019. +// Copyright Ruslan Arutyunyan, 2019-2021. +// +// 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_ANY_TEST_BASIC_TEST_HPP +#define BOOST_ANY_TEST_BASIC_TEST_HPP + +// what: unit tests for variant type boost::any +// who: contributed by Kevlin Henney +// when: July 2001, 2013, 2014 +// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 + +#include <cstdlib> +#include <string> +#include <vector> +#include <utility> + +#include <boost/type_traits/is_base_and_derived.hpp> + +#include "test.hpp" + +namespace any_tests { + +struct huge_structure { + char take_place[1024]; + std::string text; +}; + + +template <typename Any> +struct basic_tests // test definitions +{ + struct copy_counter + { + public: + copy_counter() {} + copy_counter(const copy_counter&) { ++count; } + copy_counter& operator=(const copy_counter&) { ++count; return *this; } + static int get_count() { return count; } + + private: + static int count; + }; + + static void test_default_ctor() + { + const Any value; + + check_true(value.empty(), "empty"); + check_null(boost::any_cast<int>(&value), "any_cast<int>"); + check_equal(value.type(), boost::typeindex::type_id<void>(), "type"); + } + + static void test_converting_ctor() + { + std::string text = "test message"; + Any value = text; + + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<std::string>(), "type"); + check_null(boost::any_cast<int>(&value), "any_cast<int>"); + check_non_null(boost::any_cast<std::string>(&value), "any_cast<std::string>"); + check_equal( + boost::any_cast<std::string>(value), text, + "comparing cast copy against original text"); + check_unequal( + boost::any_cast<std::string>(&value), &text, + "comparing address in copy against original text"); + } + + static void test_copy_ctor() + { + std::string text = "test message"; + Any original = text, copy = original; + + check_false(copy.empty(), "empty"); + check_equal(boost::typeindex::type_index(original.type()), copy.type(), "type"); + check_equal( + boost::any_cast<std::string>(original), boost::any_cast<std::string>(copy), + "comparing cast copy against original"); + check_equal( + text, boost::any_cast<std::string>(copy), + "comparing cast copy against original text"); + check_unequal( + boost::any_cast<std::string>(&original), + boost::any_cast<std::string>(©), + "comparing address in copy against original"); + } + + static void test_copy_assign() + { + std::string text = "test message"; + Any original = text, copy; + Any * assign_result = &(copy = original); + + check_false(copy.empty(), "empty"); + check_equal(boost::typeindex::type_index(original.type()), copy.type(), "type"); + check_equal( + boost::any_cast<std::string>(original), boost::any_cast<std::string>(copy), + "comparing cast copy against cast original"); + check_equal( + text, boost::any_cast<std::string>(copy), + "comparing cast copy against original text"); + check_unequal( + boost::any_cast<std::string>(&original), + boost::any_cast<std::string>(©), + "comparing address in copy against original"); + check_equal(assign_result, ©, "address of assignment result"); + } + + static void test_converting_assign() + { + std::string text = "test message"; + Any value; + Any * assign_result = &(value = text); + + check_false(value.empty(), "type"); + check_equal(value.type(), boost::typeindex::type_id<std::string>(), "type"); + check_null(boost::any_cast<int>(&value), "any_cast<int>"); + check_non_null(boost::any_cast<std::string>(&value), "any_cast<std::string>"); + check_equal( + boost::any_cast<std::string>(value), text, + "comparing cast copy against original text"); + check_unequal( + boost::any_cast<std::string>(&value), + &text, + "comparing address in copy against original text"); + check_equal(assign_result, &value, "address of assignment result"); + } + + static void test_bad_cast() + { + std::string text = "test message"; + Any value = text; + + TEST_CHECK_THROW( + boost::any_cast<const char *>(value), + boost::bad_any_cast, + "any_cast to incorrect type"); + } + + static void test_swap() + { + huge_structure stored; + stored.text = "test message"; + + Any original = stored; + Any swapped; + huge_structure * original_ptr = boost::any_cast<huge_structure>(&original); + Any * swap_result = &original.swap(swapped); + + check_true(original.empty(), "empty on original"); + check_false(swapped.empty(), "empty on swapped"); + check_equal(swapped.type(), boost::typeindex::type_id<huge_structure>(), "type"); + check_equal( + stored.text, boost::any_cast<huge_structure>(swapped).text, + "comparing swapped copy against original text"); + check_non_null(original_ptr, "address in pre-swapped original"); + check_equal( + original_ptr, + boost::any_cast<huge_structure>(&swapped), + "comparing address in swapped against original"); + check_equal(swap_result, &original, "address of swap result"); + + swap(swapped, swapped); + check_false(swapped.empty(), "empty on self swap"); + check_equal( + swapped.type(), boost::typeindex::type_id<huge_structure>(), + "type missmatch on self swap"); + check_equal( + stored.text, boost::any_cast<huge_structure>(swapped).text, + "comparing against original text on self swap"); + + Any copy1 = copy_counter(); + Any copy2 = copy_counter(); + int count = copy_counter::get_count(); + swap(copy1, copy2); + check_equal(count, copy_counter::get_count(), "checking that free swap doesn't make any copies."); + + Any any_char = '1'; + swap(any_char, swapped); + check_equal( + stored.text, boost::any_cast<huge_structure>(any_char).text, + "comparing against original text on swap with small type"); + check_equal( + swapped.type(), boost::typeindex::type_id<char>(), + "comparing type on swap with small type"); + check_equal( + '1', boost::any_cast<char>(swapped), + "comparing small type swapped value"); + } + + static void test_null_copying() + { + const Any null; + Any copied = null, assigned; + assigned = null; + + check_true(null.empty(), "empty on null"); + check_true(copied.empty(), "empty on copied"); + check_true(assigned.empty(), "empty on copied"); + } + + static void test_cast_to_reference() + { + Any a(137); + const Any b(a); + + int & ra = boost::any_cast<int &>(a); + int const & ra_c = boost::any_cast<int const &>(a); + int volatile & ra_v = boost::any_cast<int volatile &>(a); + int const volatile & ra_cv = boost::any_cast<int const volatile&>(a); + + check_true( + &ra == &ra_c && &ra == &ra_v && &ra == &ra_cv, + "cv references to same obj"); + + int const & rb_c = boost::any_cast<int const &>(b); + int const volatile & rb_cv = boost::any_cast<int const volatile &>(b); + + check_true(&rb_c == &rb_cv, "cv references to copied const obj"); + check_true(&ra != &rb_c, "copies hold different objects"); + + ++ra; + int incremented = boost::any_cast<int>(a); + check_true(incremented == 138, "increment by reference changes value"); + + TEST_CHECK_THROW( + boost::any_cast<char &>(a), + boost::bad_any_cast, + "any_cast to incorrect reference type"); + + TEST_CHECK_THROW( + boost::any_cast<const char &>(b), + boost::bad_any_cast, + "any_cast to incorrect const reference type"); + } + + static void test_bad_any_cast() + { + check_true( + boost::is_base_and_derived<std::exception, boost::bad_any_cast>::value, + "bad_any_cast base class check" + ); + + check_true( + std::string(boost::bad_any_cast().what()).find("any") != std::string::npos, + "bad_any_cast notes any in excaption" + ); + } + + static void test_with_array() + { + Any value1("Char array"); + Any value2; + value2 = "Char array"; + + check_false(value1.empty(), "type"); + check_false(value2.empty(), "type"); + + check_equal(value1.type(), boost::typeindex::type_id<const char*>(), "type"); + check_equal(value2.type(), boost::typeindex::type_id<const char*>(), "type"); + + check_non_null(boost::any_cast<const char*>(&value1), "any_cast<const char*>"); + check_non_null(boost::any_cast<const char*>(&value2), "any_cast<const char*>"); + } + + static void test_clear() + { + std::string text = "test message"; + Any value = text; + + check_false(value.empty(), "empty"); + + value.clear(); + check_true(value.empty(), "non-empty after clear"); + + value.clear(); + check_true(value.empty(), "non-empty after second clear"); + + value = text; + check_false(value.empty(), "empty"); + + value.clear(); + check_true(value.empty(), "non-empty after clear"); + } + + // Following tests cover the case from #9462 + // https://svn.boost.org/trac/boost/ticket/9462 + static Any makeVec() + { + return std::vector<int>(100 /*size*/, 7 /*value*/); + } + + static void test_vectors() + { + const std::vector<int>& vec = boost::any_cast<std::vector<int> >(makeVec()); + check_equal(vec.size(), 100u, "size of vector extracted from boost::any"); + check_equal(vec.back(), 7, "back value of vector extracted from boost::any"); + check_equal(vec.front(), 7, "front value of vector extracted from boost::any"); + + std::vector<int> vec1 = boost::any_cast<std::vector<int> >(makeVec()); + check_equal(vec1.size(), 100u, "size of second vector extracted from boost::any"); + check_equal(vec1.back(), 7, "back value of second vector extracted from boost::any"); + check_equal(vec1.front(), 7, "front value of second vector extracted from boost::any"); + } + + template<typename T> + class class_with_address_op + { + public: + class_with_address_op(const T* p) + : ptr(p) + {} + + const T** operator &() + { + return &ptr; + } + + const T* get() const + { + return ptr; + } + + private: + const T* ptr; + }; + + static void test_addressof() + { + int val = 10; + const int* ptr = &val; + class_with_address_op<int> obj(ptr); + Any test_val(obj); + + class_with_address_op<int> returned_obj = boost::any_cast<class_with_address_op<int> >(test_val); + check_equal(&val, returned_obj.get(), "any_cast incorrectly works with type that has operator&(): addresses differ"); + + check_true(!!boost::any_cast<class_with_address_op<int> >(&test_val), "any_cast incorrectly works with type that has operator&()"); + check_equal(boost::unsafe_any_cast<class_with_address_op<int> >(&test_val)->get(), ptr, "unsafe_any_cast incorrectly works with type that has operator&()"); + } + + static void test_multiple_assign() + { + Any test_val = 10; + check_true(!!boost::any_cast<int>(&test_val), "any_cast"); + + test_val = '0'; + check_true(!!boost::any_cast<char>(&test_val), "any_cast"); + + test_val = huge_structure(); + check_true(!!boost::any_cast<huge_structure>(&test_val), "any_cast"); + + test_val = '0'; + check_true(!!boost::any_cast<char>(&test_val), "any_cast"); + + test_val = Any(huge_structure()); + check_true(!!boost::any_cast<huge_structure>(&test_val), "any_cast"); + } + + static int run_tests() + { + typedef test<const char *, void (*)()> test_case; + const test_case test_cases[] = + { + { "default construction", test_default_ctor }, + { "single argument construction", test_converting_ctor }, + { "copy construction", test_copy_ctor }, + { "copy assignment operator", test_copy_assign }, + { "converting assignment operator", test_converting_assign }, + { "failed custom keyword cast", test_bad_cast }, + { "swap member function", test_swap }, + { "copying operations on a null", test_null_copying }, + { "cast to reference types", test_cast_to_reference }, + { "bad_any_cast exception", test_bad_any_cast }, + { "storing an array inside", test_with_array }, + { "clear() methods", test_clear }, + { "testing with vectors", test_vectors }, + { "class with operator&()", test_addressof }, + { "multiple assignments", test_multiple_assign }, + }; + typedef const test_case * test_case_iterator; + + tester<test_case_iterator> test_suite(test_cases, test_cases + sizeof(test_cases) / sizeof(test_cases[0])); + return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE; + } +}; + + +template <typename Any> +int basic_tests<Any>::copy_counter::count = 0; + +} + +#endif diff --git a/src/boost/libs/any/test/move_test.hpp b/src/boost/libs/any/test/move_test.hpp new file mode 100644 index 000000000..5fbfc7333 --- /dev/null +++ b/src/boost/libs/any/test/move_test.hpp @@ -0,0 +1,303 @@ +// See http://www.boost.org for most recent version, including documentation. +// +// Copyright Antony Polukhin, 2013-2022. +// Copyright Ruslan Arutyunyan, 2019. +// +// 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_ANY_TESTS_MOVE_TEST_HPP_INCLUDED +#define BOOST_ANY_TESTS_MOVE_TEST_HPP_INCLUDED + +#include <cstdlib> +#include <string> +#include <utility> + +#include "test.hpp" +#include <boost/move/move.hpp> +#include <boost/type_index.hpp> + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +namespace any_tests { + +template <typename Any> +struct move_tests // test definitions +{ + static void test_move_construction() + { + Any value0 = move_copy_conting_class(); + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; + Any value(boost::move(value0)); + + check(value0.empty(), "moved away value is empty"); + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<move_copy_conting_class>(), "type"); + check_non_null(boost::any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>"); + check_equal( + move_copy_conting_class::copy_count, 0u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 0u, + "checking move counts"); + } + + static void test_move_assignment() + { + Any value0 = move_copy_conting_class(); + Any value = move_copy_conting_class(); + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; + value = boost::move(value0); + + check(value0.empty(), "moved away is empty"); + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<move_copy_conting_class>(), "type"); + check_non_null(boost::any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>"); + check_equal( + move_copy_conting_class::copy_count, 0u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 0u, + "checking move counts"); + } + + static void test_copy_construction() + { + Any value0 = move_copy_conting_class(); + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; + Any value(value0); + + check_false(value0.empty(), "copied value is not empty"); + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<move_copy_conting_class>(), "type"); + check_non_null(boost::any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>"); + check_equal( + move_copy_conting_class::copy_count, 1u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 0u, + "checking move counts"); + } + + static void test_copy_assignment() + { + Any value0 = move_copy_conting_class(); + Any value = move_copy_conting_class(); + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; + value = value0; + + check_false(value0.empty(), "copied value is not empty"); + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<move_copy_conting_class>(), "type"); + check_non_null(boost::any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>"); + check_equal( + move_copy_conting_class::copy_count, 1u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 0u, + "checking move counts"); + } + + static void test_move_construction_from_value() + { + move_copy_conting_class value0; + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + Any value(boost::move(value0)); +#else + Any value(value0); +#endif + + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<move_copy_conting_class>(), "type"); + check_non_null(boost::any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>"); + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + check_equal( + move_copy_conting_class::copy_count, 0u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 1u, + "checking move counts"); +#endif + + } + + static void test_move_assignment_from_value() + { + move_copy_conting_class value0; + Any value; + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + value = boost::move(value0); +#else + value = value0; +#endif + + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<move_copy_conting_class>(), "type"); + check_non_null(boost::any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>"); + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + check_equal( + move_copy_conting_class::copy_count, 0u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 1u, + "checking move counts"); +#endif + + } + + static void test_copy_construction_from_value() + { + move_copy_conting_class value0; + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; + Any value(value0); + + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<move_copy_conting_class>(), "type"); + check_non_null(boost::any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>"); + + check_equal( + move_copy_conting_class::copy_count, 1u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 0u, + "checking move counts"); + } + + static void test_copy_assignment_from_value() + { + move_copy_conting_class value0; + Any value; + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; + value = value0; + + check_false(value.empty(), "empty"); + check_equal(value.type(), boost::typeindex::type_id<move_copy_conting_class>(), "type"); + check_non_null(boost::any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>"); + + check_equal( + move_copy_conting_class::copy_count, 1u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 0u, + "checking move counts"); + } + + static const Any helper_method() { + return true; + } + + static const bool helper_method1() { + return true; + } + + static void test_construction_from_const_any_rv() + { + Any values[] = {helper_method(), helper_method1() }; + (void)values; + } + + static void test_cast_to_rv() + { + move_copy_conting_class value0; + Any value; + value = value0; + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; + + move_copy_conting_class value1 = boost::any_cast<move_copy_conting_class&&>(value); + + check_equal( + move_copy_conting_class::copy_count, 0u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 1u, + "checking move counts"); + (void)value1; +// Following code shall fail to compile + const Any cvalue = value0; + move_copy_conting_class::copy_count = 0; + move_copy_conting_class::moves_count = 0; + + move_copy_conting_class value2 = boost::any_cast<const move_copy_conting_class&>(cvalue); + + check_equal( + move_copy_conting_class::copy_count, 1u, + "checking copy counts"); + check_equal( + move_copy_conting_class::moves_count, 0u, + "checking move counts"); + (void)value2; +// + } + + class move_copy_conting_class { + public: + static unsigned int moves_count; + static unsigned int copy_count; + + move_copy_conting_class(){} + move_copy_conting_class(move_copy_conting_class&& /*param*/) { + ++ moves_count; + } + + move_copy_conting_class& operator=(move_copy_conting_class&& /*param*/) { + ++ moves_count; + return *this; + } + + move_copy_conting_class(const move_copy_conting_class&) { + ++ copy_count; + } + move_copy_conting_class& operator=(const move_copy_conting_class& /*param*/) { + ++ copy_count; + return *this; + } + }; + + static int run_tests() { + typedef test<const char *, void (*)()> test_case; + const test_case test_cases[] = + { + { "move construction of any", test_move_construction }, + { "move assignment of any", test_move_assignment }, + { "copy construction of any", test_copy_construction }, + { "copy assignment of any", test_copy_assignment }, + + { "move construction from value", test_move_construction_from_value }, + { "move assignment from value", test_move_assignment_from_value }, + { "copy construction from value", test_copy_construction_from_value }, + { "copy assignment from value", test_copy_assignment_from_value }, + { "constructing from const any&&", test_construction_from_const_any_rv }, + { "casting to rvalue reference", test_cast_to_rv } + }; + typedef const test_case * test_case_iterator; + + tester<test_case_iterator> test_suite(test_cases, test_cases + sizeof(test_cases) / sizeof(test_cases[0])); + return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE; + } +}; // struct move_tests + +template <typename Any> +unsigned int move_tests<Any>::move_copy_conting_class::moves_count = 0; + +template <typename Any> +unsigned int move_tests<Any>::move_copy_conting_class::copy_count = 0; + +} // namespace any_tests + +#endif // BOOST_ANY_TESTS_MOVE_TEST_HPP_INCLUDED + +#endif // MOVE_TEST_INCLUDED diff --git a/src/boost/libs/any/test/test.hpp b/src/boost/libs/any/test/test.hpp new file mode 100644 index 000000000..e801041fe --- /dev/null +++ b/src/boost/libs/any/test/test.hpp @@ -0,0 +1,321 @@ +// what: simple unit test framework +// who: developed by Kevlin Henney +// when: November 2000 +// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.91 + +#ifndef TEST_INCLUDED +#define TEST_INCLUDED + +#include <boost/config.hpp> +#include <exception> +#include <iostream> +#ifdef BOOST_NO_STRINGSTREAM +#include <strstream> // for out-of-the-box g++ pre-2.95.3 +#else +#include <sstream> +#endif +#include <string> + +namespace any_tests // test tuple comprises name and nullary function (object) +{ + template<typename string_type, typename function_type> + struct test + { + string_type name; + function_type action; + + static test make(string_type name, function_type action) + { + test result; // MSVC aggreggate initializer bugs + result.name = name; + result.action = action; + return result; + } + }; +} + +namespace any_tests // failure exception used to indicate checked test failures +{ + class failure : public std::exception + { + public: // struction (default cases are OK) + + failure(const std::string & why) throw() + : reason(why) + { + } + + ~failure() throw() {} + + public: // usage + + virtual const char * what() const throw() + { + return reason.c_str(); + } + + private: // representation + + std::string reason; + + }; +} + +namespace any_tests // not_implemented exception used to mark unimplemented tests +{ + class not_implemented : public std::exception + { + public: // usage (default ctor and dtor are OK) + + virtual const char * what() const throw() + { + return "not implemented"; + } + + }; +} + +namespace any_tests // test utilities +{ + inline void check(bool condition, const std::string & description) + { + if(!condition) + { + throw failure(description); + } + } + + inline void check_true(bool value, const std::string & description) + { + check(value, "expected true: " + description); + } + + inline void check_false(bool value, const std::string & description) + { + check(!value, "expected false: " + description); + } + + template<typename lhs_type, typename rhs_type> + void check_equal( + const lhs_type & lhs, const rhs_type & rhs, + const std::string & description) + { + check(lhs == rhs, "expected equal values: " + description); + } + + template<typename lhs_type, typename rhs_type> + void check_unequal( + const lhs_type & lhs, const rhs_type & rhs, + const std::string & description) + { + check(lhs != rhs, "expected unequal values: " + description); + } + + inline void check_null(const void * ptr, const std::string & description) + { + check(!ptr, "expected null pointer: " + description); + } + + inline void check_non_null(const void * ptr, const std::string & description) + { + check(ptr != 0, "expected non-null pointer: " + description); + } +} + +#define TEST_CHECK_THROW(expression, exception, description) \ + try \ + { \ + expression; \ + throw ::any_tests::failure(description); \ + } \ + catch(exception &) \ + { \ + } + +namespace any_tests // memory tracking (enabled if test new and delete linked in) +{ + class allocations + { + public: // singleton access + + static allocations & instance() + { + static allocations singleton; + return singleton; + } + + public: // logging + + void clear() + { + alloc_count = dealloc_count = 0; + } + + void allocation() + { + ++alloc_count; + } + + void deallocation() + { + ++dealloc_count; + } + + public: // reporting + + unsigned long allocated() const + { + return alloc_count; + } + + unsigned long deallocated() const + { + return dealloc_count; + } + + bool balanced() const + { + return alloc_count == dealloc_count; + } + + private: // structors (default dtor is fine) + + allocations() + : alloc_count(0), dealloc_count(0) + { + } + + private: // prevention + + allocations(const allocations &); + allocations & operator=(const allocations &); + + private: // state + + unsigned long alloc_count, dealloc_count; + + }; +} + +namespace any_tests // tester is the driver class for a sequence of tests +{ + template<typename test_iterator> + class tester + { + public: // structors (default destructor is OK) + + tester(test_iterator first_test, test_iterator after_last_test) + : begin(first_test), end(after_last_test) + { + } + + public: // usage + + bool operator()(); // returns true if all tests passed + + private: // representation + + test_iterator begin, end; + + private: // prevention + + tester(const tester &); + tester &operator=(const tester &); + + }; + +#if defined(__GNUC__) && defined(__SGI_STL_PORT) && (__GNUC__ < 3) + // function scope using declarations don't work: + using namespace std; +#endif + + template<typename test_iterator> + bool tester<test_iterator>::operator()() + { + using std::cerr; + using std::endl; + using std::ends; + using std::exception; + using std::flush; + using std::string; + + unsigned long passed = 0, failed = 0, unimplemented = 0; + + for(test_iterator current = begin; current != end; ++current) + { + cerr << "[" << current->name << "] " << flush; + string result = "passed"; // optimistic + + try + { + allocations::instance().clear(); + current->action(); + + if(!allocations::instance().balanced()) + { + unsigned long allocated = allocations::instance().allocated(); + unsigned long deallocated = allocations::instance().deallocated(); +#ifdef BOOST_NO_STRINGSTREAM + std::ostrstream report; +#else + std::ostringstream report; +#endif + report << "new/delete (" + << allocated << " allocated, " + << deallocated << " deallocated)" + << ends; + const string text = report.str(); +#ifdef BOOST_NO_STRINGSTREAM + report.freeze(false); +#endif + throw failure(text); + } + + ++passed; + } + catch(const failure & caught) + { + (result = "failed: ") += caught.what(); + ++failed; + } + catch(const not_implemented &) + { + result = "not implemented"; + ++unimplemented; + } + catch(const exception & caught) + { + (result = "exception: ") += caught.what(); + ++failed; + } + catch(...) + { + result = "failed with unknown exception"; + ++failed; + } + + cerr << result << endl; + } + + cerr << (passed + failed) << " tests: " + << passed << " passed, " + << failed << " failed"; + + if(unimplemented) + { + cerr << " (" << unimplemented << " not implemented)"; + } + + cerr << endl; + + return failed == 0; + } +} + +#endif + +// Copyright Kevlin Henney, 2000. All rights reserved. +// +// 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) |