simplify constraints by checking for residues
[isl.git] / cpp / cpp.h.top
blob02b5a916c32ce20bafae708d7be6e054a406c7b9
1 /// These are automatically generated C++ bindings for isl.
2 ///
3 /// isl is a library for computing with integer sets and maps described by
4 /// Presburger formulas. On top of this, isl provides various tools for
5 /// polyhedral compilation, ranging from dependence analysis over scheduling
6 /// to AST generation.
8 #ifndef ISL_CPP
9 #define ISL_CPP
11 #include <isl/ctx.h>
12 #include <isl/options.h>
14 #include <functional>
15 #include <memory>
16 #include <ostream>
17 #include <stdexcept>
18 #include <string>
19 #include <type_traits>
21 #if __cplusplus >= 201703L
22 #include <any>
23 #include <optional>
24 #endif
26 /* ISL_USE_EXCEPTIONS should be defined to 1 if exceptions are available.
27  * gcc and clang define __cpp_exceptions; MSVC and xlC define _CPPUNWIND.
28  * Older versions of gcc (e.g., 4.9) only define __EXCEPTIONS.
29  * If exceptions are not available, any error condition will result
30  * in an abort.
31  */
32 #ifndef ISL_USE_EXCEPTIONS
33 #if defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(__EXCEPTIONS)
34 #define ISL_USE_EXCEPTIONS      1
35 #else
36 #define ISL_USE_EXCEPTIONS      0
37 #endif
38 #endif
40 namespace isl {
42 class ctx {
43         isl_ctx *ptr;
44 public:
45         /* implicit */ ctx(isl_ctx *ctx) : ptr(ctx) {}
46         isl_ctx *release() {
47                 auto tmp = ptr;
48                 ptr = nullptr;
49                 return tmp;
50         }
51         isl_ctx *get() {
52                 return ptr;
53         }
54 #if __cplusplus >= 201703L
55         static void free_user(void *user) {
56                 std::any *p = static_cast<std::any *>(user);
57                 delete p;
58         }
59 #endif
62 /* Macros hiding try/catch.
63  * If exceptions are not available, then no exceptions will be thrown and
64  * there is nothing to catch.
65  */
66 #if ISL_USE_EXCEPTIONS
67 #define ISL_CPP_TRY             try
68 #define ISL_CPP_CATCH_ALL       catch (...)
69 #else
70 #define ISL_CPP_TRY             if (1)
71 #define ISL_CPP_CATCH_ALL       if (0)
72 #endif
74 #if ISL_USE_EXCEPTIONS
76 /* Class capturing isl errors.
77  *
78  * The what() return value is stored in a reference counted string
79  * to ensure that the copy constructor and the assignment operator
80  * do not throw any exceptions.
81  */
82 class exception : public std::exception {
83         std::shared_ptr<std::string> what_str;
85 protected:
86         inline exception(const char *what_arg, const char *msg,
87                 const char *file, int line);
88 public:
89         exception() {}
90         exception(const char *what_arg) {
91                 what_str = std::make_shared<std::string>(what_arg);
92         }
93         static inline void throw_error(enum isl_error error, const char *msg,
94                 const char *file, int line);
95         virtual const char *what() const noexcept override {
96                 return what_str->c_str();
97         }
99         /* Default behavior on error conditions that occur inside isl calls
100          * performed from inside the bindings.
101          * In the case exceptions are available, isl should continue
102          * without printing a warning since the warning message
103          * will be included in the exception thrown from inside the bindings.
104          */
105         static constexpr auto on_error = ISL_ON_ERROR_CONTINUE;
106         /* Wrapper for throwing an exception with the given message.
107          */
108         static void throw_invalid(const char *msg, const char *file, int line) {
109                 throw_error(isl_error_invalid, msg, file, line);
110         }
111         static inline void throw_last_error(ctx ctx);
114 /* Create an exception of a type described by "what_arg", with
115  * error message "msg" in line "line" of file "file".
117  * Create a string holding the what() return value that
118  * corresponds to what isl would have printed.
119  * If no error message or no error file was set, then use "what_arg" instead.
120  */
121 exception::exception(const char *what_arg, const char *msg, const char *file,
122         int line)
124         if (!msg || !file)
125                 what_str = std::make_shared<std::string>(what_arg);
126         else
127                 what_str = std::make_shared<std::string>(std::string(file) +
128                                     ":" + std::to_string(line) + ": " + msg);
131 class exception_abort : public exception {
132         friend exception;
133         exception_abort(const char *msg, const char *file, int line) :
134                 exception("execution aborted", msg, file, line) {}
137 class exception_alloc : public exception {
138         friend exception;
139         exception_alloc(const char *msg, const char *file, int line) :
140                 exception("memory allocation failure", msg, file, line) {}
143 class exception_unknown : public exception {
144         friend exception;
145         exception_unknown(const char *msg, const char *file, int line) :
146                 exception("unknown failure", msg, file, line) {}
149 class exception_internal : public exception {
150         friend exception;
151         exception_internal(const char *msg, const char *file, int line) :
152                 exception("internal error", msg, file, line) {}
155 class exception_invalid : public exception {
156         friend exception;
157         exception_invalid(const char *msg, const char *file, int line) :
158                 exception("invalid argument", msg, file, line) {}
161 class exception_quota : public exception {
162         friend exception;
163         exception_quota(const char *msg, const char *file, int line) :
164                 exception("quota exceeded", msg, file, line) {}
167 class exception_unsupported : public exception {
168         friend exception;
169         exception_unsupported(const char *msg, const char *file, int line) :
170                 exception("unsupported operation", msg, file, line) {}
173 /* Throw an exception of the class that corresponds to "error", with
174  * error message "msg" in line "line" of file "file".
176  * isl_error_none is treated as an invalid error type.
177  */
178 void exception::throw_error(enum isl_error error, const char *msg,
179         const char *file, int line)
181         switch (error) {
182         case isl_error_none:
183                 break;
184         case isl_error_abort: throw exception_abort(msg, file, line);
185         case isl_error_alloc: throw exception_alloc(msg, file, line);
186         case isl_error_unknown: throw exception_unknown(msg, file, line);
187         case isl_error_internal: throw exception_internal(msg, file, line);
188         case isl_error_invalid: throw exception_invalid(msg, file, line);
189         case isl_error_quota: throw exception_quota(msg, file, line);
190         case isl_error_unsupported:
191                                 throw exception_unsupported(msg, file, line);
192         }
194         throw exception_invalid("invalid error type", file, line);
197 /* Throw an exception corresponding to the last error on "ctx" and
198  * reset the error.
200  * If "ctx" is NULL or if it is not in an error state at the start,
201  * then an invalid argument exception is thrown.
202  */
203 void exception::throw_last_error(ctx ctx)
205         enum isl_error error;
206         const char *msg, *file;
207         int line;
209         error = isl_ctx_last_error(ctx.get());
210         msg = isl_ctx_last_error_msg(ctx.get());
211         file = isl_ctx_last_error_file(ctx.get());
212         line = isl_ctx_last_error_line(ctx.get());
213         isl_ctx_reset_error(ctx.get());
215         throw_error(error, msg, file, line);
218 #else
220 #include <stdio.h>
221 #include <stdlib.h>
223 class exception {
224 public:
225         /* Default behavior on error conditions that occur inside isl calls
226          * performed from inside the bindings.
227          * In the case exceptions are not available, isl should abort.
228          */
229         static constexpr auto on_error = ISL_ON_ERROR_ABORT;
230         /* Wrapper for throwing an exception with the given message.
231          * In the case exceptions are not available, print an error and abort.
232          */
233         static void throw_invalid(const char *msg, const char *file, int line) {
234                 fprintf(stderr, "%s:%d: %s\n", file, line, msg);
235                 abort();
236         }
237         /* Throw an exception corresponding to the last
238          * error on "ctx".
239          * isl should already abort when an error condition occurs,
240          * so this function should never be called.
241          */
242         static void throw_last_error(ctx ctx) {
243                 abort();
244         }
247 #endif
249 /* Helper class for setting the on_error and resetting the option
250  * to the original value when leaving the scope.
251  */
252 class options_scoped_set_on_error {
253         isl_ctx *ctx;
254         int saved_on_error;
255 public:
256         options_scoped_set_on_error(class ctx ctx, int on_error) {
257                 this->ctx = ctx.get();
258                 saved_on_error = isl_options_get_on_error(this->ctx);
259                 isl_options_set_on_error(this->ctx, on_error);
260         }
261         ~options_scoped_set_on_error() {
262                 isl_options_set_on_error(ctx, saved_on_error);
263         }
266 } // namespace isl