[DEV] add v1.66.0

This commit is contained in:
2018-01-12 21:47:58 +01:00
parent 87059bb1af
commit a97e9ae7d4
49032 changed files with 7668950 additions and 0 deletions

20
libs/any/test/Jamfile.v2 Normal file
View File

@@ -0,0 +1,20 @@
# Copyright Vladimur 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
#
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 ]
;

View File

@@ -0,0 +1,14 @@
// Copyright 2006 Alexander Nasonov.
//
// 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);
}

405
libs/any/test/any_test.cpp Normal file
View File

@@ -0,0 +1,405 @@
// 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/any.hpp>
#include "test.hpp"
namespace any_tests
{
typedef test<const char *, void (*)()> test_case;
typedef const test_case * test_case_iterator;
extern const test_case_iterator begin, end;
}
int main()
{
using namespace any_tests;
tester<test_case_iterator> 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_cast_to_reference();
void test_with_array();
void test_with_func();
void test_clear();
void test_vectors();
void test_addressof();
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 },
{ "storing an array inside", test_with_array },
{ "implicit cast of returned value",test_with_func },
{ "clear() methods", test_clear },
{ "testing with vectors", test_vectors },
{ "class with operator&()", test_addressof }
};
const test_case_iterator begin = test_cases;
const test_case_iterator end =
test_cases + (sizeof test_cases / sizeof *test_cases);
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;
};
int copy_counter::count = 0;
}
namespace any_tests // test definitions
{
using namespace boost;
void test_default_ctor()
{
const any value;
check_true(value.empty(), "empty");
check_null(any_cast<int>(&value), "any_cast<int>");
check_equal(value.type(), boost::typeindex::type_id<void>(), "type");
}
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(any_cast<int>(&value), "any_cast<int>");
check_non_null(any_cast<std::string>(&value), "any_cast<std::string>");
check_equal(
any_cast<std::string>(value), text,
"comparing cast copy against original text");
check_unequal(
any_cast<std::string>(&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(boost::typeindex::type_index(original.type()), copy.type(), "type");
check_equal(
any_cast<std::string>(original), any_cast<std::string>(copy),
"comparing cast copy against original");
check_equal(
text, any_cast<std::string>(copy),
"comparing cast copy against original text");
check_unequal(
any_cast<std::string>(&original),
any_cast<std::string>(&copy),
"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(boost::typeindex::type_index(original.type()), copy.type(), "type");
check_equal(
any_cast<std::string>(original), any_cast<std::string>(copy),
"comparing cast copy against cast original");
check_equal(
text, any_cast<std::string>(copy),
"comparing cast copy against original text");
check_unequal(
any_cast<std::string>(&original),
any_cast<std::string>(&copy),
"comparing address in copy against original");
check_equal(assign_result, &copy, "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(), boost::typeindex::type_id<std::string>(), "type");
check_null(any_cast<int>(&value), "any_cast<int>");
check_non_null(any_cast<std::string>(&value), "any_cast<std::string>");
check_equal(
any_cast<std::string>(value), text,
"comparing cast copy against original text");
check_unequal(
any_cast<std::string>(&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<const char *>(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<std::string>(&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<std::string>(), "type");
check_equal(
text, any_cast<std::string>(swapped),
"comparing swapped copy against original text");
check_non_null(original_ptr, "address in pre-swapped original");
check_equal(
original_ptr,
any_cast<std::string>(&swapped),
"comparing address in swapped against original");
check_equal(swap_result, &original, "address of swap result");
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.");
}
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_cast_to_reference()
{
any a(137);
const any b(a);
int & ra = any_cast<int &>(a);
int const & ra_c = any_cast<int const &>(a);
int volatile & ra_v = any_cast<int volatile &>(a);
int const volatile & ra_cv = 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 = any_cast<int const &>(b);
int const volatile & rb_cv = 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 = any_cast<int>(a);
check_true(incremented == 138, "increment by reference changes value");
TEST_CHECK_THROW(
any_cast<char &>(a),
bad_any_cast,
"any_cast to incorrect reference type");
TEST_CHECK_THROW(
any_cast<const char &>(b),
bad_any_cast,
"any_cast to incorrect const reference type");
}
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(any_cast<const char*>(&value1), "any_cast<const char*>");
check_non_null(any_cast<const char*>(&value2), "any_cast<const char*>");
}
const std::string& returning_string1()
{
static const std::string ret("foo");
return ret;
}
std::string returning_string2()
{
static const std::string ret("foo");
return ret;
}
void test_with_func()
{
std::string s;
s = any_cast<std::string>(returning_string1());
s = any_cast<const std::string&>(returning_string1());
s = any_cast<std::string>(returning_string2());
s = 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 = any_cast<std::string&&>(returning_string1());
#endif
s = any_cast<std::string&&>(returning_string2());
#endif
}
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
boost::any makeVec()
{
return std::vector<int>(100 /*size*/, 7 /*value*/);
}
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;
};
void test_addressof()
{
int val = 10;
const int* ptr = &val;
class_with_address_op<int> obj(ptr);
boost::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&()");
}
}
// Copyright Kevlin Henney, 2000, 2001. All rights reserved.
// Copyright Antony Polukhin, 2013-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)
//

View File

@@ -0,0 +1,39 @@
// Unit test for boost::any.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2013-2014.
//
// 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

View File

@@ -0,0 +1,19 @@
// Copyright Antony Polukhin, 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)
// 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';
}

View File

@@ -0,0 +1,331 @@
// Unit test for boost::any.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2013-2014.
//
// 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()
{
return EXIT_SUCCESS;
}
#else
namespace any_tests
{
typedef test<const char *, void (*)()> test_case;
typedef const test_case * test_case_iterator;
extern const test_case_iterator begin, end;
}
int main()
{
using namespace any_tests;
tester<test_case_iterator> test_suite(begin, end);
return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE;
}
namespace any_tests // test suite
{
void test_move_construction();
void test_move_assignment();
void test_copy_construction();
void test_copy_assignment();
void test_move_construction_from_value();
void test_move_assignment_from_value();
void test_copy_construction_from_value();
void test_copy_assignment_from_value();
void test_construction_from_const_any_rv();
void test_cast_to_rv();
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 }
};
const test_case_iterator begin = test_cases;
const test_case_iterator end =
test_cases + (sizeof test_cases / sizeof *test_cases);
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;
}
};
unsigned int move_copy_conting_class::moves_count = 0;
unsigned int move_copy_conting_class::copy_count = 0;
}
namespace any_tests // test definitions
{
using namespace boost;
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(), typeindex::type_id<move_copy_conting_class>(), "type");
check_non_null(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");
}
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(), typeindex::type_id<move_copy_conting_class>(), "type");
check_non_null(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");
}
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(), "copyed value is not empty");
check_false(value.empty(), "empty");
check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
check_non_null(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");
}
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(), "copyied value is not empty");
check_false(value.empty(), "empty");
check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
check_non_null(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");
}
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(), typeindex::type_id<move_copy_conting_class>(), "type");
check_non_null(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
}
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(), typeindex::type_id<move_copy_conting_class>(), "type");
check_non_null(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
}
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(), typeindex::type_id<move_copy_conting_class>(), "type");
check_non_null(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");
}
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(), typeindex::type_id<move_copy_conting_class>(), "type");
check_non_null(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");
}
const any helper_method() {
return true;
}
const bool helper_method1() {
return true;
}
void test_construction_from_const_any_rv()
{
any values[] = {helper_method(), helper_method1() };
(void)values;
}
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 = 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 = any_cast<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;
*/
}
}
#endif

View File

@@ -0,0 +1,38 @@
// Unit test for boost::any.
//
// See http://www.boost.org for most recent version, including documentation.
//
// Copyright Antony Polukhin, 2013-2014.
//
// 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

321
libs/any/test/test.hpp Normal file
View File

@@ -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)