chiark / gitweb /
support exceptions in SWIG wrappers
authorstevenj <stevenj@alum.mit.edu>
Fri, 4 Jun 2010 02:03:46 +0000 (22:03 -0400)
committerstevenj <stevenj@alum.mit.edu>
Fri, 4 Jun 2010 02:03:46 +0000 (22:03 -0400)
darcs-hash:20100604020346-c8de0-b94b0853daeba61580499c4385089737b6d9d221.gz

api/nlopt-in.hpp
api/options.c
swig/Makefile.am
swig/nlopt-exceptions.i [new file with mode: 0644]
swig/nlopt.i

index 08f89f11179214b080875100e4bf16ea6cdb76f2..a44cd8ccabb6a943ea84a5f5a1c9e2bc9ef8984f 100644 (file)
@@ -223,7 +223,7 @@ namespace nlopt {
 
     // Nonlinear constraints:
 
-    void remove_inequality_constraints(void) {
+    void remove_inequality_constraints() {
       nlopt_result ret = nlopt_remove_inequality_constraints(o);
       mythrow(ret);
     }
@@ -241,7 +241,7 @@ namespace nlopt {
       alloc_tmp();
     }
 
-    void remove_equality_constraints(void) {
+    void remove_equality_constraints() {
       nlopt_result ret = nlopt_remove_equality_constraints(o);
       mythrow(ret);
     }
@@ -261,16 +261,14 @@ namespace nlopt {
 
 #define NLOPT_GETSET_VEC(name)                                         \
     void set_##name(double val) {                                      \
-      nlopt_result ret = nlopt_set_##name##1(o, val);                  \
-      mythrow(ret);                                                    \
+      mythrow(nlopt_set_##name##1(o, val));                            \
     }                                                                  \
     void get_##name(std::vector<double> &v) const {                    \
       if (o && nlopt_get_dimension(o) != v.size())                     \
         throw std::invalid_argument("dimension mismatch");             \
-      nlopt_result ret = nlopt_get_##name(o, v.empty() ? NULL : &v[0]);        \
-      mythrow(ret);                                                    \
+      mythrow(nlopt_get_##name(o, v.empty() ? NULL : &v[0]));          \
     }                                                                  \
-    std::vector<double> get_##name(void) const {                       \
+    std::vector<double> get_##name() const {                   \
       if (!o) throw std::runtime_error("uninitialized nlopt::opt");    \
       std::vector<double> v(nlopt_get_dimension(o));                   \
       get_##name(v);                                                   \
@@ -279,8 +277,7 @@ namespace nlopt {
     void set_##name(const std::vector<double> &v) {                    \
       if (o && nlopt_get_dimension(o) != v.size())                     \
         throw std::invalid_argument("dimension mismatch");             \
-      nlopt_result ret = nlopt_set_##name(o, v.empty() ? NULL : &v[0]);        \
-      mythrow(ret);                                                    \
+      mythrow(nlopt_set_##name(o, v.empty() ? NULL : &v[0]));          \
     }
 
     NLOPT_GETSET_VEC(lower_bounds)
@@ -294,8 +291,7 @@ namespace nlopt {
       return nlopt_get_##name(o);                                      \
     }                                                                  \
     void set_##name(T name) {                                          \
-      nlopt_result ret = nlopt_set_##name(o, name);                    \
-      mythrow(ret);                                                    \
+      mythrow(nlopt_set_##name(o, name));                              \
     }
     NLOPT_GETSET(double, stopval)
     NLOPT_GETSET(double, ftol_rel)
@@ -344,12 +340,27 @@ namespace nlopt {
 
   //////////////////////////////////////////////////////////////////////
 
-  inline void srand(unsigned long seed) { nlopt_srand(seed); }
-  inline void srand_time(void) { nlopt_srand_time(); }
-  inline void version(int &major, int &minor, int &bugfix) {
+  void srand(unsigned long seed) { nlopt_srand(seed); }
+  void srand_time() { nlopt_srand_time(); }
+  void version(int &major, int &minor, int &bugfix) {
     nlopt_version(&major, &minor, &bugfix);
   }
-  inline const char *algorithm_name(algorithm a) {
+  int version_major() {
+    int major, minor, bugfix;
+    nlopt_version(&major, &minor, &bugfix);
+    return major;
+  }
+  int version_minor() {
+    int major, minor, bugfix;
+    nlopt_version(&major, &minor, &bugfix);
+    return minor;
+  }
+  int version_bugfix() {
+    int major, minor, bugfix;
+    nlopt_version(&major, &minor, &bugfix);
+    return bugfix;
+  }
+  const char *algorithm_name(algorithm a) {
     return nlopt_algorithm_name(nlopt_algorithm(a));
   }
 
index 614ec005bf55e8fdd2e1e610f1a489eb4ea0b9c6..e766ca4bd1c9bde0cc86b9d3ac33d4d6678ec999 100644 (file)
@@ -261,6 +261,7 @@ nlopt_result nlopt_get_upper_bounds(nlopt_opt opt, double *ub)
 
 nlopt_result nlopt_remove_inequality_constraints(nlopt_opt opt)
 {
+     if (!opt) return NLOPT_INVALID_ARGS;
      free(opt->fc);
      opt->fc = NULL;
      opt->m = opt->m_alloc = 0;
@@ -313,6 +314,7 @@ nlopt_result nlopt_add_inequality_constraint(nlopt_opt opt,
 
 nlopt_result nlopt_remove_equality_constraints(nlopt_opt opt)
 {
+     if (!opt) return NLOPT_INVALID_ARGS;
      free(opt->h);
      opt->h = NULL;
      opt->p = opt->p_alloc = 0;
index 4766ade40108b48b7ec1cfaca1f290bf6fffb575..3700643ccff56f2bc7a958ab1da6b9eccf1a18fd 100644 (file)
@@ -1,4 +1,5 @@
-EXTRA_DIST = nlopt.i nlopt-guile.i nlopt-enum-renames.i nlopt.scm.in
+SWIG_SRC = nlopt.i nlopt-exceptions.i nlopt-enum-renames.i 
+EXTRA_DIST = $(SWIG_SRC) nlopt-guile.i nlopt.scm.in
 
 BUILT_SOURCES = nlopt-guile.cpp nlopt-enum-renames.i nlopt.scm.in
 
@@ -29,7 +30,7 @@ lib_LTLIBRARIES = $(guilelib)
 
 if MAINTAINER_MODE
 
-nlopt-guile.cpp: nlopt.i nlopt-enum-renames.i nlopt-guile.i $(HDR)
+nlopt-guile.cpp: $(SWIG_SRC) nlopt-guile.i $(HDR)
        swig -I$(top_builddir)/api -outdir $(builddir) -c++ -guile -scmstub -o $@ nlopt.i
        rm -f nlopt.scm.in
        mv nlopt.scm nlopt.scm.in
diff --git a/swig/nlopt-exceptions.i b/swig/nlopt-exceptions.i
new file mode 100644 (file)
index 0000000..e7693da
--- /dev/null
@@ -0,0 +1,59 @@
+// since exception specifications in C++ are evil, we instead provide
+// %catches specifications here so that SWIG can generate language-specific
+// exceptions (at least for exceptions explicitly thrown by NLopt)
+//
+// manually doing this stuff is annoying
+
+%catches(std::bad_alloc) nlopt::opt::opt();
+%catches(std::bad_alloc) nlopt::opt::opt(algorithm a, unsigned n);
+%catches(std::bad_alloc) nlopt::opt::opt(const opt& f);
+%catches(std::bad_alloc) nlopt::opt::operator=(opt const& f);
+
+%catches(nlopt::roundoff_limited,nlopt::forced_stop,std::runtime_error,std::bad_alloc,std::invalid_argument) nlopt::opt::optimize(std::vector<double> &x, double &opt_f);
+%catches(nlopt::roundoff_limited,nlopt::forced_stop,std::runtime_error,std::bad_alloc,std::invalid_argument) nlopt::opt::optimize(const std::vector<double> &x0);
+
+%catches(std::runtime_error) nlopt::opt::get_algorithm();
+%catches(std::runtime_error) nlopt::opt::get_algorithm_name();
+%catches(std::runtime_error) nlopt::opt::get_dimension();
+
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::set_min_objective(func f, void *f_data);
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::set_min_objective(vfunc vf, void *f_data);
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::set_max_objective(func f, void *f_data);
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::set_max_objective(vfunc vf, void *f_data);
+
+%catches(std::invalid_argument) nlopt::opt::remove_inequality_constraints();
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::add_inequality_constraint(func f, void *f_data, double tol=0);
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::add_inequality_constraint(vfunc vf, void *f_data, double tol=0);
+%catches(std::invalid_argument) nlopt::opt::remove_equality_constraints();
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::add_equality_constraint(func f, void *f_data, double tol=0);
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::add_equality_constraint(vfunc vf, void *f_data, double tol=0);
+
+#define SET_EXCEPT(name, T) %catches(std::invalid_argument) nlopt::opt::set_##name(T val);
+#define GET_EXCEPT(name) %catches(std::invalid_argument) nlopt::opt::get_##name();
+#define SETVEC_EXCEPT(name) %catches(std::invalid_argument) nlopt::opt::set_##name(const std::vector<double> &v);
+#define GETVEC_EXCEPT(name) %catches(std::bad_alloc,std::invalid_argument) nlopt::opt::get_##name(std::vector<double> &v);
+#define GETSET_EXCEPT(name, T) GET_EXCEPT(name) SET_EXCEPT(name, T)
+#define GETSETVEC_EXCEPT(name) GET_EXCEPT(name) SET_EXCEPT(name, double) GETVEC_EXCEPT(name) SETVEC_EXCEPT(name)
+
+GETSETVEC_EXCEPT(lower_bounds)
+GETSETVEC_EXCEPT(upper_bounds)
+
+GETSET_EXCEPT(stopval, double)
+GETSET_EXCEPT(ftol_rel, double)
+GETSET_EXCEPT(ftol_abs, double)
+GETSET_EXCEPT(xtol_rel, double)
+GETSETVEC_EXCEPT(xtol_abs)
+GETSET_EXCEPT(maxeval, int)
+GETSET_EXCEPT(maxtime, double)
+GETSET_EXCEPT(force_stop, int)
+
+%catches(std::invalid_argument) nlopt::opt::force_stop();
+
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::set_local_optimizer(const opt &lo);
+
+GETSET_EXCEPT(local_population, unsigned)
+GETSETVEC_EXCEPT(initial_step)
+
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::set_default_initial_step(const std::vector<double> &x);
+%catches(std::invalid_argument) nlopt::opt::get_initial_step(const std::vector<double> &x, std::vector<double> &dx);
+%catches(std::bad_alloc,std::invalid_argument) nlopt::opt::get_initial_step(const std::vector<double> &x);
index 01dc67959a3ed5f656e993d70f1a9ed004b236cf..6f6f0b4c629840e55e50a877e77754d23e11ec53 100644 (file)
@@ -18,6 +18,8 @@ namespace std {
 %rename(nlopt_algorithm_name) nlopt::algorithm_name;
 %include "nlopt-enum-renames.i"
 
+%include "nlopt-exceptions.i"
+
 #ifdef SWIGGUILE
 %include "nlopt-guile.i"
 #endif