123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- #ifndef __CXXCALL_TESTS_UTILS__
- #define __CXXCALL_TESTS_UTILS__ 1
- #include <iostream>
- #include <cstdlib>
- #include <string>
- #include <vector>
- #include <utility>
- #include <tuple>
- #include <typeinfo>
- #include <sstream>
- #define ASSERT(Cond) \
- do \
- { \
- if (!(Cond)) \
- { \
- std::cerr << "\n\nAssertion failed: " << #Cond << \
- "\nLine: " << __LINE__ << "\nFile: " << __FILE__ << \
- "\nFunction: " << cur_fname << "\n\n"; \
- exit (EXIT_FAILURE); \
- } \
- } \
- while (false)
- #define CONCAT_(x, y) x ## y
- #define CONCAT(x, y) CONCAT_(x, y)
- #define TUPLE std::make_tuple
- static std::string cur_fname;
- struct test_fn
- {
- std::string msg;
- void (*fct) ();
- test_fn (const std::string& m, void (*f) ()) : msg (m), fct (f)
- {
- }
- void run () const
- {
- std::cout << "Testing " << this->msg << "...";
- this->fct ();
- std::cout << " OK\n";
- }
- };
- std::vector<test_fn>& test_suite ()
- {
- static std::vector<test_fn> ts;
- return (ts);
- }
- void run_tests ()
- {
- for (auto& tst : test_suite ())
- tst.run ();
- std::cout << "Done\n";
- }
- struct test_module
- {
- typedef std::pair<std::string, void (*) ()> pair_type;
- test_module (const char *name, std::initializer_list<pair_type> tests)
- {
- std::string nm = std::string (" (") + name + ") ";
- for (auto pair : tests)
- test_suite().push_back (test_fn (pair.first + nm, pair.second));
- }
- };
- template <class T>
- struct equal
- {
- template <class ...Args>
- static bool eq (void *addr, T (*fn) (Args...), Args... args)
- {
- return (*(const T *)addr == fn (args...));
- }
- };
- template <>
- struct equal<void>
- {
- static bool eq (void *, ...)
- {
- return (true);
- }
- };
- static void *global_tuple;
- template <class T>
- static bool eq_tuples (const T& left)
- {
- return (left == *(const T *)global_tuple);
- }
- template <class ...>
- struct sum_type;
- template <class T>
- struct sum_type<T>
- {
- typedef T type;
- };
- template <class T, class ...Args>
- struct sum_type<T, Args...>
- {
- typedef typename sum_type<Args...>::type rtype;
- typedef decltype (std::declval<T>() + std::declval<rtype>()) type;
- };
- template <class T>
- T sum (T x)
- {
- std::ostringstream ostr;
- ostr << "sum (" << typeid(x).name () << ")";
- cur_fname = ostr.str ();
- ASSERT (eq_tuples (TUPLE (x)));
- return (x);
- }
- template <class T>
- void print_type (std::ostringstream& ostr, T x)
- {
- ostr << typeid(x).name () << ", ";
- }
- template <class T, class ...Args>
- auto sum (T x, Args... args) -> typename sum_type<T, Args...>::type
- {
- std::ostringstream ostr;
- ostr << "sum (";
- using helper_type = int[];
- helper_type { (print_type (ostr, x), 0), (print_type (ostr, args), 0)... };
- std::string s = ostr.str ();
- s.erase (s.end () - 2, s.end ());
- cur_fname = s + ')';
- ASSERT (eq_tuples (TUPLE (x, args...)));
- return (x + sum (args...));
- }
- #endif
|