1
2#include <stdio.h>
3#include <stdlib.h>
4
5#include <functional>
6#include <memory>
7#include <ostream>
8#include <string>
9#include <type_traits>
10
11namespace isl {
12namespace checked {
13
14#define ISLPP_STRINGIZE_(X) #X
15#define ISLPP_STRINGIZE(X) ISLPP_STRINGIZE_(X)
16
17#define ISLPP_ASSERT(test, message)                          \
18  do {                                                       \
19    if (test)                                                \
20      break;                                                 \
21    fputs("Assertion \"" #test "\" failed at " __FILE__      \
22      ":" ISLPP_STRINGIZE(__LINE__) "\n  " message "\n",     \
23      stderr);                                               \
24    abort();                                                 \
25  } while (0)
26
27/* Class used to check that isl::checked::boolean,
28 * isl::checked::stat and isl::checked::size values are checked for errors.
29 */
30struct checker {
31	bool checked = false;
32	~checker() {
33		ISLPP_ASSERT(checked, "IMPLEMENTATION ERROR: Unchecked state");
34	}
35};
36
37class boolean {
38private:
39  mutable std::shared_ptr<checker> check = std::make_shared<checker>();
40  isl_bool val;
41
42  friend boolean manage(isl_bool val);
43  boolean(isl_bool val): val(val) {}
44public:
45  static boolean error() {
46    return boolean(isl_bool_error);
47  }
48  boolean()
49      : val(isl_bool_error) {}
50
51  /* implicit */ boolean(bool val)
52      : val(val ? isl_bool_true : isl_bool_false) {}
53
54  isl_bool release() {
55    auto tmp = val;
56    val = isl_bool_error;
57    check->checked = true;
58    return tmp;
59  }
60
61  bool is_error() const { check->checked = true; return val == isl_bool_error; }
62  bool is_false() const { check->checked = true; return val == isl_bool_false; }
63  bool is_true() const { check->checked = true; return val == isl_bool_true; }
64
65  explicit operator bool() const {
66    ISLPP_ASSERT(check->checked, "IMPLEMENTATION ERROR: Unchecked error state");
67    ISLPP_ASSERT(!is_error(), "IMPLEMENTATION ERROR: Unhandled error state");
68    return is_true();
69  }
70
71  boolean negate() {
72    if (val == isl_bool_true)
73      val = isl_bool_false;
74    else if (val == isl_bool_false)
75      val = isl_bool_true;
76    return *this;
77  }
78
79  boolean operator!() const {
80    return boolean(*this).negate();
81  }
82};
83
84inline boolean manage(isl_bool val) {
85  return boolean(val);
86}
87
88class ctx {
89  isl_ctx *ptr;
90public:
91  /* implicit */ ctx(isl_ctx *ctx)
92      : ptr(ctx) {}
93  isl_ctx *release() {
94    auto tmp = ptr;
95    ptr = nullptr;
96    return tmp;
97  }
98  isl_ctx *get() {
99    return ptr;
100  }
101};
102
103/* Class encapsulating an isl_stat value.
104 */
105class stat {
106private:
107	mutable std::shared_ptr<checker> check = std::make_shared<checker>();
108	isl_stat val;
109
110	friend stat manage(isl_stat val);
111	stat(isl_stat val) : val(val) {}
112public:
113	static stat ok() {
114		return stat(isl_stat_ok);
115	}
116	static stat error() {
117		return stat(isl_stat_error);
118	}
119	stat() : val(isl_stat_error) {}
120
121	isl_stat release() {
122		check->checked = true;
123		return val;
124	}
125
126	bool is_error() const {
127		check->checked = true;
128		return val == isl_stat_error;
129	}
130	bool is_ok() const {
131		check->checked = true;
132		return val == isl_stat_ok;
133	}
134};
135
136inline stat manage(isl_stat val)
137{
138	return stat(val);
139}
140
141/* Class encapsulating an isl_size value.
142 */
143class size {
144private:
145	mutable std::shared_ptr<checker> check = std::make_shared<checker>();
146	isl_size val;
147
148	friend size manage(isl_size val);
149	size(isl_size val) : val(val) {}
150public:
151	size() : val(isl_size_error) {}
152
153	isl_size release() {
154		auto tmp = val;
155		val = isl_size_error;
156		check->checked = true;
157		return tmp;
158	}
159
160	bool is_error() const {
161		check->checked = true;
162		return val == isl_size_error;
163	}
164
165	explicit operator unsigned() const {
166		ISLPP_ASSERT(check->checked,
167			    "IMPLEMENTATION ERROR: Unchecked error state");
168		ISLPP_ASSERT(!is_error(),
169			    "IMPLEMENTATION ERROR: Unhandled error state");
170		return val;
171	}
172};
173
174inline size manage(isl_size val)
175{
176	return size(val);
177}
178
179}
180} // namespace isl
181