File: safe_math_test.h

package info (click to toggle)
safeint 3.0.28a%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,668 kB
  • sloc: cpp: 24,880; ansic: 3,183; makefile: 53
file content (108 lines) | stat: -rw-r--r-- 2,400 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Licensed under the MIT License.
// Copyright David LeBlanc - dcl@dleblanc.net

#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4365) // signed/unsigned mismatch in iostream
#endif

#include <exception>
#include <assert.h>
#include <iostream>
#include <string>
#include <cstdint>

#if defined _MSC_VER
#pragma warning(pop)
#pragma warning(disable: 4514 5045 4464 4820)
#endif


#if defined __clang__ || defined __GNUC__
#define NORETURN __attribute__((noreturn))
#elif defined _MSC_VER
#define NORETURN __declspec(noreturn)
#else
#define NORETURN
#endif

// This has to be done in C++ so we can catch exceptions, not abort
NORETURN inline void safe_math_fail(const char* msg)
{
	throw std::runtime_error(msg);
}

#define SAFE_MATH_FAIL_DEFINED
#include "../../safe_math.h"
#include "../TestCase.h"

// Suppress warnings in test files
#if defined _MSC_VER
#pragma warning(disable: 4838)
#endif

template <typename T, typename U>
struct check_test
{
	template<typename F>
	bool operator()(F f, T t, U u, T* ret)
	{
		return f(t, u, ret);
	}
};

template <typename T, typename U>
struct safe_test
{
	template<typename F>
	T operator()(F f, T t, U u)
	{
		return f(t, u);
	}
};

template <typename T, typename U, typename F1, typename F2, int op>
void test_base(const char* type_str, F1 fcn1, F2 fcn2)
{
	TestVector< T, U, op > tests;
	TestCase<T, U, op > test = tests.GetNext();

	while (!tests.Done())
	{
		T ret;

		// err_msg(std::string(OpName::op_name(op)) + "_test_" + type_str + " enter: ", test.x, test.y, test.fExpected);

		check_test<T, U> ct;
		bool result = ct.operator()(fcn1, test.x, test.y, &ret);

		if (!!result != test.fExpected)
		{
			std::string msg = std::string("Failure in ") + OpName::op_name(op) + "_test_" + type_str;
			// err_msg(msg, test.x, test.y, test.fExpected);
			throw std::runtime_error(msg.c_str());
		}

		bool actual;
		try
		{
			safe_test<T, U> st;
			ret = st.operator()(fcn2, test.x, test.y);
			actual = true;
		}
		catch (...)
		{
			actual = false;
		}

		if (actual != test.fExpected)
		{
			std::string msg = std::string("Failure in ") + OpName::op_name(op) + "_test_" + type_str;
			// err_msg(msg, test.x, test.y, test.fExpected);
			throw std::runtime_error(msg.c_str());
		}

		// err_msg(std::string(OpName::op_name(op)) + "_test_" + type_str + " completed: ", test.x, test.y, test.fExpected);
		test = tests.GetNext();
	}
}