// what: unit tests for variant type boost::any // who: contributed by Kevlin Henney // when: July 2001 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 #include #include #include #include "boost/any.hpp" #include "test.hpp" namespace any_tests { typedef test test_case; typedef const test_case * test_case_iterator; extern const test_case_iterator begin, end; } int main() { using namespace any_tests; tester test_suite(begin, end); return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE; } namespace any_tests // test suite { void test_default_ctor(); void test_converting_ctor(); void test_copy_ctor(); void test_copy_assign(); void test_converting_assign(); void test_bad_cast(); void test_swap(); void test_null_copying(); void test_ref(); void test_cv(); 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 }, { "casting to references", test_ref }, { "cv qualifiers", test_cv } }; const test_case_iterator begin = test_cases; const test_case_iterator end = test_cases + (sizeof test_cases / sizeof *test_cases); } // Used in test_cv function struct cv_tester { cv_tester() {} cv_tester(cv_tester const volatile&) {} }; BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(cv_tester) namespace any_tests // test definitions { using namespace boost; void test_default_ctor() { const any value; check_true(value.empty(), "empty"); check_null(any_cast(&value), "any_cast"); check_equal(value.type(), typeid(void), "type"); } void test_converting_ctor() { std::string text = "test message"; any value = text; check_false(value.empty(), "empty"); check_equal(value.type(), typeid(std::string), "type"); check_null(any_cast(&value), "any_cast"); check_non_null(any_cast(&value), "any_cast"); check_equal( any_cast(value), text, "comparing cast copy against original text"); check_unequal( any_cast(&value), &text, "comparing address in copy against original text"); } void test_copy_ctor() { std::string text = "test message"; any original = text, copy = original; check_false(copy.empty(), "empty"); check_equal(original.type(), copy.type(), "type"); check_equal( any_cast(original), any_cast(copy), "comparing cast copy against original"); check_equal( text, any_cast(copy), "comparing cast copy against original text"); check_unequal( any_cast(&original), any_cast(©), "comparing address in copy against original"); } 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(original.type(), copy.type(), "type"); check_equal( any_cast(original), any_cast(copy), "comparing cast copy against cast original"); check_equal( text, any_cast(copy), "comparing cast copy against original text"); check_unequal( any_cast(&original), any_cast(©), "comparing address in copy against original"); check_equal(assign_result, ©, "address of assignment result"); } 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(), typeid(std::string), "type"); check_null(any_cast(&value), "any_cast"); check_non_null(any_cast(&value), "any_cast"); check_equal( any_cast(value), text, "comparing cast copy against original text"); check_unequal( any_cast(&value), &text, "comparing address in copy against original text"); check_equal(assign_result, &value, "address of assignment result"); } void test_bad_cast() { std::string text = "test message"; any value = text; TEST_CHECK_THROW( any_cast(value), bad_any_cast, "any_cast to incorrect type"); } void test_swap() { std::string text = "test message"; any original = text, swapped; std::string * original_ptr = any_cast(&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(), typeid(std::string), "type"); check_equal( text, any_cast(swapped), "comparing swapped copy against original text"); check_non_null(original_ptr, "address in pre-swapped original"); check_equal( original_ptr, any_cast(&swapped), "comparing address in swapped against original"); check_equal(swap_result, &original, "address of swap result"); } 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"); } void test_ref() { int volatile i = 7; any a(i), b(a); const any c(i); int& ra1 = any_cast(a); int const& ra2 = any_cast(a); int const volatile& ra3 = any_cast(a); check_true( &ra1 == &ra2 && &ra2 == &ra3, "references refer to a same object"); int& rb1 = any_cast(b); int const& rb2 = any_cast(b); int const volatile& rb3 = any_cast(b); check_true( &rb1 == &rb2 && &rb2 == &rb3, "references refer to a same object"); int const& rc1 = any_cast(c); int const volatile& rc2 = any_cast(c); check_true(&rc1 == &rc2, "references refer to a same object"); check_true( &ra1 != &rb1 && &rb1 != &rc1 && &rc1 != &ra1, "references refer to different objects"); check_true( &ra1 != &i && &rb1 != &i && &rc1 != &i, "references don't refer to original"); ++ra1; check_true(any_cast(a) == i + 1, "modified through reference"); --rb1; check_true(any_cast(b) == i - 1, "modified through reference"); TEST_CHECK_THROW( any_cast(a), bad_any_cast, "any_cast to incorrect reference type"); } void test_cv() { cv_tester t; cv_tester const tc(t); cv_tester const volatile tcv(t); cv_tester const volatile* p; any a(t); any atc(tc); any atcv(tcv); any_cast(a); any_cast(a); any_cast(a); p = &any_cast(a); p = &any_cast(a); p = &any_cast(a); p = any_cast(&a); p = any_cast(&a); p = any_cast(&a); any const ac(t); any const actc(tc); any const actcv(tcv); any_cast(ac); any_cast(ac); any_cast(ac); p = &any_cast(ac); p = &any_cast(ac); p = any_cast(&ac); p = any_cast(&ac); } } // Copyright Kevlin Henney, 2000, 2001. 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) //