1 /* Implementation of the C interface: declarations. 2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com) 4 5 This file is part of the Parma Polyhedra Library (PPL). 6 7 The PPL is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by the 9 Free Software Foundation; either version 3 of the License, or (at your 10 option) any later version. 11 12 The PPL is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software Foundation, 19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 20 21 For the most up-to-date information see the Parma Polyhedra Library 22 site: http://bugseng.com/products/ppl/ . */ 23 24 #ifndef PPL_ppl_c_implementation_common_defs_hh 25 #define PPL_ppl_c_implementation_common_defs_hh 1 26 27 #define PPL_NO_AUTOMATIC_INITIALIZATION 28 #include "ppl.hh" 29 #include "ppl_c.h" 30 #include <stdexcept> 31 32 namespace Parma_Polyhedra_Library { 33 34 namespace Interfaces { 35 36 namespace C { 37 38 extern "C" typedef void 39 (*error_handler_type)(enum ppl_enum_error_code code, const char* description); 40 41 extern error_handler_type user_error_handler; 42 43 void notify_error(enum ppl_enum_error_code code, const char* description); 44 45 Relation_Symbol relation_symbol(enum ppl_enum_Constraint_Type t); 46 47 Bounded_Integer_Type_Width 48 bounded_integer_type_width(enum ppl_enum_Bounded_Integer_Type_Width w); 49 50 Bounded_Integer_Type_Representation 51 bounded_integer_type_representation(enum ppl_enum_Bounded_Integer_Type_Representation r); 52 53 /*! \brief 54 A class to wrap an array of fixed length into a partial function interface 55 suitable for the map_space_dimension() methods. 56 */ 57 class Array_Partial_Function_Wrapper { 58 public: 59 /*! \brief 60 Construct a partial function wrapping the first \p n positions of 61 \p v. 62 */ 63 Array_Partial_Function_Wrapper(dimension_type* v, size_t n); 64 65 /*! \brief 66 Returns <CODE>true</CODE> if and only if the represented partial 67 function has an empty codomain (i.e., it is always undefined). 68 */ 69 bool has_empty_codomain() const; 70 71 /*! \brief 72 Returns the maximum value that belongs to the codomain 73 of the partial function. 74 */ 75 dimension_type max_in_codomain() const; 76 77 /*! \brief 78 Assigns to \p j the value associated to \p i by \p *this, if any. 79 80 Let \f$f\f$ be the function represented by \p *this and \f$k\f$ be 81 the value of \p i. If \f$f\f$ is defined in \f$k\f$, then 82 \f$f(k)\f$ is assigned to \p j and <CODE>true</CODE> is returned. 83 If \f$f\f$ is undefined in \f$k\f$, then <CODE>false</CODE> is 84 returned. 85 */ 86 bool maps(dimension_type i, dimension_type& j) const; 87 88 private: 89 //! Holds the vector implementing the map. 90 dimension_type* vec; 91 92 //! Holds the size of \p vec. 93 size_t vec_size; 94 95 //! Cache for computing the maximum dimension in the codomain. 96 mutable dimension_type max_in_codomain_; 97 98 //! Cache for computing emptiness: 99 //! -1 if we still don't know, 0 if not empty, 1 if empty. 100 mutable int empty; 101 }; 102 103 class timeout_exception : public Parma_Polyhedra_Library::Throwable { 104 public: throw_me() const105 void throw_me() const { 106 throw *this; 107 } priority() const108 int priority() const { 109 return 0; 110 } 111 }; 112 113 void reset_timeout(); 114 115 class deterministic_timeout_exception 116 : public Parma_Polyhedra_Library::Throwable { 117 public: throw_me() const118 void throw_me() const { 119 throw *this; 120 } priority() const121 int priority() const { 122 return 0; 123 } 124 }; 125 126 void reset_deterministic_timeout(); 127 128 } // namespace C 129 130 } // namespace Interfaces 131 132 } // namespace Parma_Polyhedra_Library 133 134 135 #define CATCH_STD_EXCEPTION(exception, code) \ 136 catch (const std::exception& e) { \ 137 notify_error(code, e.what()); \ 138 return code; \ 139 } 140 141 #define CATCH_ALL \ 142 CATCH_STD_EXCEPTION(bad_alloc, PPL_ERROR_OUT_OF_MEMORY) \ 143 CATCH_STD_EXCEPTION(invalid_argument, PPL_ERROR_INVALID_ARGUMENT) \ 144 CATCH_STD_EXCEPTION(domain_error, PPL_ERROR_DOMAIN_ERROR) \ 145 CATCH_STD_EXCEPTION(length_error, PPL_ERROR_LENGTH_ERROR) \ 146 CATCH_STD_EXCEPTION(logic_error, PPL_ERROR_LOGIC_ERROR) \ 147 CATCH_STD_EXCEPTION(overflow_error, PPL_ARITHMETIC_OVERFLOW) \ 148 CATCH_STD_EXCEPTION(runtime_error, PPL_ERROR_INTERNAL_ERROR) \ 149 CATCH_STD_EXCEPTION(exception, PPL_ERROR_UNKNOWN_STANDARD_EXCEPTION) \ 150 catch (timeout_exception&) { \ 151 reset_timeout(); \ 152 notify_error(PPL_TIMEOUT_EXCEPTION, "PPL timeout expired"); \ 153 return PPL_TIMEOUT_EXCEPTION; \ 154 } \ 155 catch (deterministic_timeout_exception&) { \ 156 reset_deterministic_timeout(); \ 157 notify_error(PPL_TIMEOUT_EXCEPTION, "PPL deterministic timeout expired"); \ 158 return PPL_TIMEOUT_EXCEPTION; \ 159 } \ 160 catch (...) { \ 161 notify_error(PPL_ERROR_UNEXPECTED_ERROR, \ 162 "completely unexpected error: a bug in the PPL"); \ 163 return PPL_ERROR_UNEXPECTED_ERROR; \ 164 } 165 166 #define DECLARE_CONVERSIONS(Type, CPP_Type) \ 167 inline const CPP_Type* \ 168 to_const(ppl_const_##Type##_t x) { \ 169 return reinterpret_cast<const CPP_Type*>(x); \ 170 } \ 171 \ 172 inline CPP_Type* \ 173 to_nonconst(ppl_##Type##_t x) { \ 174 return reinterpret_cast<CPP_Type*>(x); \ 175 } \ 176 \ 177 inline ppl_const_##Type##_t \ 178 to_const(const CPP_Type* x) { \ 179 return reinterpret_cast<ppl_const_##Type##_t>(x); \ 180 } \ 181 \ 182 inline ppl_##Type##_t \ 183 to_nonconst(CPP_Type* x) { \ 184 return reinterpret_cast<ppl_##Type##_t>(x); \ 185 } 186 187 #define DEFINE_PRINT_FUNCTIONS(Type) \ 188 int \ 189 ppl_io_print_##Type(ppl_const_##Type##_t x) try { \ 190 using namespace IO_Operators; \ 191 stdiobuf sb(stdout); \ 192 std::ostream os(&sb); \ 193 os << *to_const(x); \ 194 if (!os) \ 195 return PPL_STDIO_ERROR; \ 196 return 0; \ 197 } \ 198 CATCH_ALL \ 199 \ 200 int \ 201 ppl_io_fprint_##Type(FILE* file, ppl_const_##Type##_t x) try { \ 202 using namespace IO_Operators; \ 203 stdiobuf sb(file); \ 204 std::ostream os(&sb); \ 205 os << *to_const(x); \ 206 if (!os) \ 207 return PPL_STDIO_ERROR; \ 208 return 0; \ 209 } \ 210 CATCH_ALL \ 211 \ 212 int \ 213 ppl_io_asprint_##Type(char** strp, ppl_const_##Type##_t x) try { \ 214 using namespace IO_Operators; \ 215 std::ostringstream os; \ 216 os << *to_const(x); \ 217 if (!os) \ 218 return PPL_STDIO_ERROR; \ 219 *strp = strdup(os.str().c_str()); \ 220 if (*strp == 0) \ 221 return PPL_ERROR_OUT_OF_MEMORY; \ 222 return 0; \ 223 } \ 224 CATCH_ALL 225 226 #define DEFINE_ASCII_DUMP_FUNCTIONS(Type) \ 227 int \ 228 ppl_##Type##_ascii_dump(ppl_const_##Type##_t x, FILE* file) try { \ 229 stdiobuf sb(file); \ 230 std::ostream os(&sb); \ 231 to_const(x)->ascii_dump(os); \ 232 if (!os) \ 233 return PPL_STDIO_ERROR; \ 234 return 0; \ 235 } \ 236 CATCH_ALL 237 238 #define DEFINE_ASCII_LOAD_FUNCTIONS(Type) \ 239 int \ 240 ppl_##Type##_ascii_load(ppl_##Type##_t x, FILE* file) try { \ 241 stdiobuf sb(file); \ 242 std::istream is(&sb); \ 243 if (!to_nonconst(x)->ascii_load(is)) \ 244 return PPL_STDIO_ERROR; \ 245 return 0; \ 246 } \ 247 CATCH_ALL 248 249 #define DEFINE_ASCII_DUMP_LOAD_FUNCTIONS(Type) \ 250 DEFINE_ASCII_DUMP_FUNCTIONS(Type) \ 251 DEFINE_ASCII_LOAD_FUNCTIONS(Type) 252 253 #define DEFINE_OUTPUT_FUNCTIONS(Type) \ 254 DEFINE_PRINT_FUNCTIONS(Type) \ 255 DEFINE_ASCII_DUMP_LOAD_FUNCTIONS(Type) 256 257 #include "ppl_c_implementation_common_inlines.hh" 258 259 #endif // !defined(PPL_ppl_c_implementation_common_defs_hh) 260