Update headers, fix style for some py files
[alexxy/gromacs.git] / src / python / sip / options / pyoptionsholder.sip
index aba7e35a991eaa7c29240d3983dc291815faed27..0b4e57412de6fd8ae857d73110087c77e3e0f613 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -45,7 +45,7 @@ class PyOptionsHolder {
 public:
     class DuplicateOption : public std::exception {
     public:
-        virtual const char* what() const noexcept;
+        virtual const char* what() const throw();
     };
     class StringList {
     public:
@@ -57,12 +57,12 @@ public:
         size_t size;
         const std::vector<std::string> *vector;
     };
-    gmx::DoubleOption doubleOption(const char*, size_t = 1, double = 0);
-    gmx::IntegerOption integerOption(const char*, size_t = 1, int = 0);
-    gmx::StringOption stringOption(const char*, size_t = 1, const char* = "");
+    gmx::DoubleOption doubleOption(const char*, size_t = 1, double* = NULL);
+    gmx::IntegerOption integerOption(const char*, size_t = 1, int* = NULL);
+    gmx::StringOption stringOption(const char*, size_t = 1, const char* = NULL);
     gmx::BooleanOption booleanOption(const char*, size_t = 1, bool = 0);
     gmx::SelectionOption selectionOption(const char*, size_t = 1);
-    gmx::FileNameOption fileNameOption(const char*, size_t = 1, const char* = 0);
+    gmx::FileNameOption fileNameOption(const char*, size_t = 1);
     PyObject* get_value(const char*);
     ~PyOptionsHolder();
 private:
@@ -71,9 +71,10 @@ private:
         const char *type;
         int *count;
         bool vector;
+        const char *name;
     };
     std::map<std::string, option_value> storage;
-    template<typename T, typename U> option_value createStorage(gmx::OptionTemplate<T, U>&, const char*, int);
+    template<typename T, typename U> U createStorage(const char*, const char*, int, const T* = 0);
     template<typename T> PyObject* buildValue(const char*, const option_value&, const sipTypeDef* = NULL, size_t = 0);
     template<typename T> void deleteStorage(const option_value&);
 };
@@ -82,7 +83,7 @@ private:
 %ModuleCode
 #include "gromacs/utility/gmxassert.h"
 
-const char* PyOptionsHolder::DuplicateOption::what() const noexcept {
+const char* PyOptionsHolder::DuplicateOption::what() const throw() {
     return "This option is already defined";
 }
 
@@ -100,61 +101,73 @@ const char* PyOptionsHolder::StringList::operator[](size_t i) {
     return vector ? (*vector)[i].data() : list[i].data();
 }
 
-template<typename T, typename U> PyOptionsHolder::option_value PyOptionsHolder::createStorage(gmx::OptionTemplate<T, U> &option, const char *type, int count) {
+template<typename T, typename U> U PyOptionsHolder::createStorage(const char *name, const char *type, int count, const T *def) {
+    if (storage.count(name))
+        throw DuplicateOption();
+
+    U option(name);
+
+    option_value value;
+    value.type = type;
+    value.count = new int;
+    value.name = name;
+
     if (count == 0) { // std::vector of values
-        auto *store = new std::vector<T>();
+        std::vector<T> *store = new std::vector<T>();
         option.storeVector(store);
         option.multiValue();
+        option.storeCount(value.count);
 
-        auto *count = new int;
-        option.storeCount(count);
+        *value.count = 0;
+        if (def) {
+            store->push_back(*def);
+            *value.count = 1;
+        }
 
-        return { store, type, count, true };
+        value.value = store;
+        value.vector = true;
     } else { // exactly `count` values
-        auto *store = new T[count];
+        T *store = new T[count];
+        if (def)
+            store[0] = *def;
+
         option.store(store);
         if (count > 1)
             option.valueCount(count);
 
-        auto *count = new int;
-        option.storeCount(count);
-
-        return { store, type, count, false };
+        value.value = store;
+        value.vector = false;
+        *value.count = count;
     }
-}
 
-gmx::DoubleOption PyOptionsHolder::doubleOption(const char *name, size_t count, double def) {
-    if (storage.count(name))
-        throw DuplicateOption();
+    storage[name] = value;
+    return option;
+}
 
-    gmx::DoubleOption option(name);
-    storage[name] = createStorage(option, "d", count);
+gmx::DoubleOption PyOptionsHolder::doubleOption(const char *name, size_t count, double *def) {
+    gmx::DoubleOption option = createStorage<double, gmx::DoubleOption>(name, "d", count, def);
 
     return option;
 }
 
-gmx::IntegerOption PyOptionsHolder::integerOption(const char *name, size_t count, int def) {
-    if (storage.count(name))
-        throw DuplicateOption();
-
-    gmx::IntegerOption option(name);
-    storage[name] = createStorage(option, "i", count);
+gmx::IntegerOption PyOptionsHolder::integerOption(const char *name, size_t count, int *def) {
+    gmx::IntegerOption option = createStorage<int, gmx::IntegerOption>(name, "i", count, def);
 
     return option;
 }
 
 gmx::StringOption PyOptionsHolder::stringOption(const char *name, size_t count, const char* def) {
-    if (storage.count(name))
-        throw DuplicateOption();
+    std::string *s_def = NULL;
+    if (def)
+        s_def = new std::string(def);
 
-    gmx::StringOption option(name);
-    storage[name] = createStorage(option, "A", count);
-    // FIXME: following does not work
-    //option.defaultValue(std::string(def));
+    gmx::StringOption option = createStorage<std::string, gmx::StringOption>(name, "A", count, s_def);
+    delete s_def;
 
     return option;
 }
 
+// FIXME: Unify with the rest
 gmx::BooleanOption PyOptionsHolder::booleanOption(const char *name, size_t count, bool def) {
     if (storage.count(name))
         throw DuplicateOption();
@@ -163,28 +176,20 @@ gmx::BooleanOption PyOptionsHolder::booleanOption(const char *name, size_t count
     *store = def;
     gmx::BooleanOption option(name);
     option.store(store);
-    storage[name] = {store, "b"};
+    option_value value = {store, "b"};
+    storage[name] = value;
 
     return option;
 }
 
 gmx::SelectionOption PyOptionsHolder::selectionOption(const char *name, size_t count) {
-    if (storage.count(name))
-        throw DuplicateOption();
-
-    gmx::SelectionOption option(name);
-    storage[name] = createStorage(option, "S", count);
+    gmx::SelectionOption option = createStorage<gmx::Selection, gmx::SelectionOption>(name, "S", count);
 
     return option;
 }
 
-gmx::FileNameOption PyOptionsHolder::fileNameOption(const char *name, size_t count, const char* def) {
-    if (storage.count(name))
-        throw DuplicateOption();
-
-    gmx::FileNameOption option(name);
-    storage[name] = createStorage(option, "f", count);
-    option.defaultBasename(def); // Docs say to set default value like this
+gmx::FileNameOption PyOptionsHolder::fileNameOption(const char *name, size_t count) {
+    gmx::FileNameOption option = createStorage<std::string, gmx::FileNameOption>(name, "f", count);
 
     return option;
 }
@@ -251,23 +256,23 @@ template<typename T> void PyOptionsHolder::deleteStorage(const PyOptionsHolder::
 }
 
 PyOptionsHolder::~PyOptionsHolder() {
-    for (auto e : storage)
-        switch (*e.second.type) {
+    for (std::map<std::string, option_value>::iterator it = storage.begin(); it != storage.end(); it++)
+        switch (*(it->second.type)) {
             case 'd': // double
-                deleteStorage<double>(e.second);
+                deleteStorage<double>(it->second);
                 break;
             case 'i': // int
-                deleteStorage<int>(e.second);
+                deleteStorage<int>(it->second);
                 break;
             case 'A': // std::string
             case 'f': // FileNameOption (the storage type is still std::string)
-                deleteStorage<std::string>(e.second);
+                deleteStorage<std::string>(it->second);
                 break;
             case 'b': // bool
-                delete (bool*) e.second.value;
+                delete (bool*) it->second.value;
                 break;
             case 'S': // Selection
-                deleteStorage<gmx::Selection>(e.second);
+                deleteStorage<gmx::Selection>(it->second);
                 break;
         }
 }
@@ -301,12 +306,21 @@ public:
             }
         %End
     };
-    DoubleOption doubleOption(const char *name, int count = 1, double def = 0) throw (PyOptionsHolder::DuplicateOption);
-    IntegerOption integerOption(const char *name, int count = 1, int def = 0) throw (PyOptionsHolder::DuplicateOption);
-    StringOption stringOption(const char *name, int count = 1, const char *def = 0) throw (PyOptionsHolder::DuplicateOption);
-    BooleanOption booleanOption(const char *name, int count = 1, bool def = 0) throw (PyOptionsHolder::DuplicateOption);
-    SelectionOption selectionOption(const char *name, int count = 1) throw (PyOptionsHolder::DuplicateOption);
-    FileNameOption fileNameOption(const char *name, int count = 1, const char *def = 0) throw (PyOptionsHolder::DuplicateOption);
+    // These methods are given twice to workaround sip setting 0 for when '*def = NULL' option is not given
+    DoubleOption doubleOption(const char *name /KeepReference/, int count = 1) throw (PyOptionsHolder::DuplicateOption);
+    DoubleOption doubleOption(const char *name /KeepReference/, int count, const double *def) throw (PyOptionsHolder::DuplicateOption);
+
+    IntegerOption integerOption(const char *name /KeepReference/, int count = 1) throw (PyOptionsHolder::DuplicateOption);
+    IntegerOption integerOption(const char *name /KeepReference/, int count, const int *def) throw (PyOptionsHolder::DuplicateOption);
+
+    StringOption stringOption(const char *name /KeepReference/, int count = 1) throw (PyOptionsHolder::DuplicateOption);
+    StringOption stringOption(const char *name /KeepReference/, int count, const char *def) throw (PyOptionsHolder::DuplicateOption);
+
+    BooleanOption booleanOption(const char *name /KeepReference/, int count = 1, bool def = 0) throw (PyOptionsHolder::DuplicateOption);
+
+    SelectionOption selectionOption(const char *name /KeepReference/, int count = 1) throw (PyOptionsHolder::DuplicateOption);
+
+    FileNameOption fileNameOption(const char *name /KeepReference/, int count = 1) throw (PyOptionsHolder::DuplicateOption);
     SIP_PYOBJECT __getitem__(const char *name);
     %MethodCode
         sipRes = sipCpp->get_value(a0);