reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
/* Copyright 2016-2017 Tobias Grosser
 *
 * Use of this software is governed by the MIT license
 *
 * Written by Tobias Grosser, Weststrasse 47, CH-8003, Zurich
 */

#include <vector>
#include <string>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <isl/options.h>
#include <isl/cpp.h>

static void die_impl(const char *file, int line, const char *message)
{
	fprintf(stderr, "Assertion failed in %s:%d %s\n", file, line, message);
	exit(EXIT_FAILURE);
}

static void assert_impl(bool condition, const char *file, int line,
	const char *message)
{
	if (condition)
		return;

	return die_impl(file, line, message);
}

#define die(msg) die_impl(__FILE__, __LINE__, msg)
#define assert(exp) assert_impl(exp, __FILE__, __LINE__, #exp)

#include "isl_test_cpp-generic.cc"

/* Test that isl_bool values are returned correctly.
 *
 * In particular, check the conversion to bool in case of true and false, and
 * exception throwing in case of error.
 */
static void test_return_bool(isl::ctx ctx)
{
	isl::set empty(ctx, "{ : false }");
	isl::set univ(ctx, "{ : }");
	isl::set null;

	bool b_true = empty.is_empty();
	bool b_false = univ.is_empty();
	bool caught = false;
	try {
		null.is_empty();
		die("no exception raised");
	} catch (const isl::exception_invalid &e) {
		caught = true;
	}

	assert(b_true);
	assert(!b_false);
	assert(caught);
}

/* Test that return values are handled correctly.
 *
 * Test that isl C++ objects, integers, boolean values, and strings are
 * returned correctly.
 */
static void test_return(isl::ctx ctx)
{
	test_return_obj(ctx);
	test_return_int(ctx);
	test_return_bool(ctx);
	test_return_string(ctx);
}

/* Test that foreach functions are modeled correctly.
 *
 * Verify that lambdas are correctly called as callback of a 'foreach'
 * function and that variables captured by the lambda work correctly. Also
 * check that the foreach function handles exceptions thrown from
 * the lambda and that it propagates the exception.
 */
static void test_foreach(isl::ctx ctx)
{
	isl::set s(ctx, "{ [0]; [1]; [2] }");

	std::vector<isl::basic_set> basic_sets;

	auto add_to_vector = [&] (isl::basic_set bs) {
		basic_sets.push_back(bs);
	};

	s.foreach_basic_set(add_to_vector);

	assert(basic_sets.size() == 3);
	assert(isl::set(basic_sets[0]).is_subset(s));
	assert(isl::set(basic_sets[1]).is_subset(s));
	assert(isl::set(basic_sets[2]).is_subset(s));
	assert(!basic_sets[0].is_equal(basic_sets[1]));

	auto fail = [&] (isl::basic_set bs) {
		throw "fail";
	};

	bool caught = false;
	try {
		s.foreach_basic_set(fail);
		die("no exception raised");
	} catch (char const *s) {
		caught = true;
	}
	assert(caught);
}

/* Test that an exception is generated for an isl error and
 * that the error message is captured by the exception.
 * Also check that the exception can be copied and that copying
 * does not throw any exceptions.
 */
static void test_exception(isl::ctx ctx)
{
	isl::multi_union_pw_aff mupa(ctx, "[]");
	isl::exception copy;

	static_assert(std::is_nothrow_copy_constructible<isl::exception>::value,
		"exceptions must be nothrow-copy-constructible");
	static_assert(std::is_nothrow_assignable<isl::exception,
						isl::exception>::value,
		"exceptions must be nothrow-assignable");

	try {
		auto umap = isl::union_map::from(mupa);
	} catch (const isl::exception_unsupported &error) {
		die("caught wrong exception");
	} catch (const isl::exception &error) {
		assert(strstr(error.what(), "without explicit domain"));
		copy = error;
	}
	assert(strstr(copy.what(), "without explicit domain"));
}

/* Test the (unchecked) isl C++ interface
 *
 * This includes:
 *  - The isl C <-> C++ pointer interface
 *  - Object construction
 *  - Different parameter types
 *  - Different return types
 *  - Foreach functions
 *  - Exceptions
 */
int main()
{
	isl_ctx *ctx = isl_ctx_alloc();

	isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);

	test_pointer(ctx);
	test_constructors(ctx);
	test_parameters(ctx);
	test_return(ctx);
	test_foreach(ctx);
	test_exception(ctx);

	isl_ctx_free(ctx);

	return EXIT_SUCCESS;
}