Use exceptions in selection evaluation.
authorTeemu Murtola <teemu.murtola@cbr.su.se>
Thu, 8 Sep 2011 15:37:48 +0000 (18:37 +0300)
committerTeemu Murtola <teemu.murtola@gmail.com>
Sat, 3 Dec 2011 19:05:20 +0000 (21:05 +0200)
Converted also the rest of selection compilation, because it internally
uses the evaluation engine.

Will add some unit tests for error conditions in a subsequent commit.

Part of task #655.

Change-Id: I7f3fc705888a02a7cd99e46952129996ee49e4cc

26 files changed:
share/template/template.cpp
src/gromacs/selection/compiler.cpp
src/gromacs/selection/evaluate.cpp
src/gromacs/selection/evaluate.h
src/gromacs/selection/mempool.cpp
src/gromacs/selection/mempool.h
src/gromacs/selection/nbsearch.cpp
src/gromacs/selection/nbsearch.h
src/gromacs/selection/selectioncollection-impl.h
src/gromacs/selection/selectioncollection.cpp
src/gromacs/selection/selectioncollection.h
src/gromacs/selection/selelem.cpp
src/gromacs/selection/selelem.h
src/gromacs/selection/selmethod.h
src/gromacs/selection/sm_compare.cpp
src/gromacs/selection/sm_distance.cpp
src/gromacs/selection/sm_insolidangle.cpp
src/gromacs/selection/sm_keywords.cpp
src/gromacs/selection/sm_merge.cpp
src/gromacs/selection/sm_permute.cpp
src/gromacs/selection/sm_position.cpp
src/gromacs/selection/sm_same.cpp
src/gromacs/selection/sm_simple.cpp
src/gromacs/selection/tests/selectioncollection.cpp
src/gromacs/trajectoryanalysis/cmdlinerunner.cpp
src/gromacs/trajectoryanalysis/nbsearch.h

index e91b90adb8e8ccac5e99f377e77d977152981f06..246e669729b7acf991cb8e517d79541f5abb426d 100644 (file)
@@ -28,6 +28,7 @@
  *
  * For more info, check our website at http://www.gromacs.org
  */
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -170,15 +171,9 @@ TrajectoryAnalysisModuleData *
 AnalysisTemplate::startFrames(AnalysisDataParallelOptions opt,
                               const SelectionCollection &selections)
 {
-    ModuleData *pdata = new ModuleData(this, opt, selections);
-    int rc = NeighborhoodSearch::create(&pdata->_nb, _cutoff, _refsel->posCount());
-    if (rc != 0)
-    {
-        delete pdata;
-        // FIXME: Use exceptions in the neighborhood search API
-        GMX_THROW(InternalError("Neighborhood search initialization failed"));
-    }
-    return pdata;
+    std::auto_ptr<ModuleData> pdata(new ModuleData(this, opt, selections));
+    pdata->_nb = new NeighborhoodSearch(_cutoff, _refsel->posCount());
+    return pdata.release();
 }
 
 
@@ -189,12 +184,7 @@ AnalysisTemplate::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
     AnalysisDataHandle *dh = pdata->dataHandle("avedist");
     NeighborhoodSearch *nb = static_cast<ModuleData *>(pdata)->_nb;
 
-    int rc = nb->init(pbc, _refsel->positions());
-    if (rc != 0)
-    {
-        // FIXME: Use exceptions in the neighborhood search API
-        GMX_THROW(InternalError("Neighborhood search frame initialization failed"));
-    }
+    nb->init(pbc, _refsel->positions());
     dh->startFrame(frnr, fr.time);
     for (size_t g = 0; g < _sel.size(); ++g)
     {
index 7efd30bd9c2ad5a232b737a3db21e201e65855ae..055f47df116c9fe328485cd7bdd8f07500f41522 100644 (file)
 #include <string2.h>
 #include <vec.h>
 
+// FIXME: Should really be in the beginning, but causes compilation errors
+#include <algorithm>
+
 #include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/indexutil.h"
 #include "gromacs/selection/poscalc.h"
 #include "selectioncollection-impl.h"
 #include "selelem.h"
 
-static int min(int a, int b)
-{
-    return (a < b) ? a : b;
-}
+using std::min;
 
 /*! \internal \brief
  * Compiler flags.
@@ -316,6 +316,8 @@ enum
     SEL_CDATA_EVALMAX     =  8,
     /** Whether memory has been allocated for \p gmin and \p gmax. */
     SEL_CDATA_MINMAXALLOC = 16,
+    /** Whether to update \p gmin and \p gmax in static analysis. */
+    SEL_CDATA_DOMINMAX      = 128,
     /** Whether subexpressions use simple pass evaluation functions. */
     SEL_CDATA_SIMPLESUBEXPR = 32,
     /** Whether this expressions is a part of a common subexpression. */
@@ -1138,7 +1140,7 @@ init_item_evalfunc(t_selelem *sel)
             break;
 
         case SEL_GROUPREF:
-            GMX_THROW(gmx::InconsistentInputError("Unresolved group reference in compilation"));
+            GMX_THROW(gmx::APIError("Unresolved group reference in compilation"));
     }
 }
 
@@ -1504,7 +1506,7 @@ init_item_minmax_groups(t_selelem *sel)
         }
         else
         {
-            sel->cdata->flags |= SEL_CDATA_MINMAXALLOC;
+            sel->cdata->flags |= SEL_CDATA_MINMAXALLOC | SEL_CDATA_DOMINMAX;
             snew(sel->cdata->gmin, 1);
             snew(sel->cdata->gmax, 1);
         }
@@ -1682,21 +1684,17 @@ make_static(t_selelem *sel)
  * \param[in]     g   The evaluation group.
  * \returns       0 on success, a non-zero error code on error.
  */
-static int
+static void
 process_const(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
-    int  rc;
-
-    rc = 0;
     if (sel->v.type == GROUP_VALUE)
     {
         if (sel->cdata->evaluate)
         {
-            rc = sel->cdata->evaluate(data, sel, g);
+            sel->cdata->evaluate(data, sel, g);
         }
     }
     /* Other constant expressions do not need evaluation */
-    return rc;
 }
 
 /*! \brief
@@ -1747,12 +1745,11 @@ store_param_val(t_selelem *sel)
  * If no \ref SPAR_ATOMVAL parameters are present, multiple initialization
  * is prevented by using \ref SEL_METHODINIT and \ref SEL_OUTINIT flags.
  */
-static int
+static void
 init_method(t_selelem *sel, t_topology *top, int isize)
 {
     t_selelem *child;
     gmx_bool       bAtomVal;
-    int        rc;
 
     /* Find out whether there are any atom-valued parameters */
     bAtomVal = FALSE;
@@ -1771,23 +1768,15 @@ init_method(t_selelem *sel, t_topology *top, int isize)
         && (bAtomVal || !(sel->flags & SEL_METHODINIT)))
     {
         sel->flags |= SEL_METHODINIT;
-        rc = sel->u.expr.method->init(top, sel->u.expr.method->nparams,
+        sel->u.expr.method->init(top, sel->u.expr.method->nparams,
                 sel->u.expr.method->param, sel->u.expr.mdata);
-        if (rc != 0)
-        {
-            return rc;
-        }
     }
     if (bAtomVal || !(sel->flags & SEL_OUTINIT))
     {
         sel->flags |= SEL_OUTINIT;
         if (sel->u.expr.method->outinit)
         {
-            rc = sel->u.expr.method->outinit(top, &sel->v, sel->u.expr.mdata);
-            if (rc != 0)
-            {
-                return rc;
-            }
+            sel->u.expr.method->outinit(top, &sel->v, sel->u.expr.mdata);
             if (sel->v.type != POS_VALUE && sel->v.type != GROUP_VALUE)
             {
                 alloc_selection_data(sel, isize, TRUE);
@@ -1809,8 +1798,7 @@ init_method(t_selelem *sel, t_topology *top, int isize)
                 /* A sanity check */
                 if (sel->v.type != STR_VALUE)
                 {
-                    gmx_bug("internal error");
-                    return -1;
+                    GMX_THROW(gmx::InternalError("Char-valued selection method in non-string element"));
                 }
                 sel->flags |= SEL_ALLOCDATA;
                 for (i = 0; i < isize; ++i)
@@ -1833,8 +1821,6 @@ init_method(t_selelem *sel, t_topology *top, int isize)
             }
         }
     }
-
-    return 0;
 }
 
 /*! \brief
@@ -1848,12 +1834,11 @@ init_method(t_selelem *sel, t_topology *top, int isize)
  *
  * reorder_item_static_children() should have been called.
  */
-static int
+static void
 evaluate_gmx_boolean_static_part(gmx_sel_evaluate_t *data, t_selelem *sel,
                              gmx_ana_index_t *g)
 {
     t_selelem *child, *next;
-    int        rc;
 
     /* Find the last static subexpression */
     child = sel->child;
@@ -1863,7 +1848,7 @@ evaluate_gmx_boolean_static_part(gmx_sel_evaluate_t *data, t_selelem *sel,
     }
     if (!(child->cdata->flags & SEL_CDATA_STATIC))
     {
-        return 0;
+        return;
     }
 
     /* Evalute the static part if there is more than one expression */
@@ -1871,11 +1856,7 @@ evaluate_gmx_boolean_static_part(gmx_sel_evaluate_t *data, t_selelem *sel,
     {
         next  = child->next;
         child->next = NULL;
-        rc = sel->cdata->evaluate(data, sel, g);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        sel->cdata->evaluate(data, sel, g);
         /* Replace the subexpressions with the result */
         _gmx_selelem_free_chain(sel->child);
         snew(child, 1);
@@ -1894,11 +1875,7 @@ evaluate_gmx_boolean_static_part(gmx_sel_evaluate_t *data, t_selelem *sel,
     }
     else if (child->evaluate)
     {
-        rc = child->evaluate(data, child, g);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        child->evaluate(data, child, g);
     }
     /* Set the evaluation function for the constant element.
      * We never need to evaluate the element again during compilation,
@@ -1934,7 +1911,6 @@ evaluate_gmx_boolean_static_part(gmx_sel_evaluate_t *data, t_selelem *sel,
             gmx_ana_index_copy(&child->u.cgrp, child->v.u.g, TRUE);
         }
     }
-    return 0;
 }
 
 /*! \brief
@@ -2026,7 +2002,7 @@ evaluate_gmx_boolean_minmax_grps(t_selelem *sel, gmx_ana_index_t *g,
             break;
 
         case BOOL_XOR: /* Should not be reached */
-            gmx_impl("xor expressions not implemented");
+            GMX_THROW(gmx::NotImplementedError("xor expressions not implemented"));
             break;
     }
 }
@@ -2050,19 +2026,18 @@ evaluate_gmx_boolean_minmax_grps(t_selelem *sel, gmx_ana_index_t *g,
  * another pass is required for subexpressions that are referred to more than
  * once and whose evaluation group is not known in advance.
  */
-static int
+static void
 analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     t_selelem       *child, *next;
     gmx_bool             bDoMinMax;
-    int              rc;
 
     if (sel->type != SEL_ROOT && g)
     {
         alloc_selection_data(sel, g->isize, FALSE);
     }
 
-    bDoMinMax = (sel->cdata->flags & SEL_CDATA_MINMAXALLOC);
+    bDoMinMax = (sel->cdata->flags & SEL_CDATA_DOMINMAX);
     if (sel->type != SEL_SUBEXPR && bDoMinMax)
     {
         gmx_ana_index_deinit(sel->cdata->gmin);
@@ -2070,29 +2045,20 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
     }
 
     /* TODO: This switch is awfully long... */
-    rc = 0;
     switch (sel->type)
     {
         case SEL_CONST:
-            rc = process_const(data, sel, g);
+            process_const(data, sel, g);
             break;
 
         case SEL_EXPRESSION:
         case SEL_MODIFIER:
-            rc = _gmx_sel_evaluate_method_params(data, sel, g);
-            if (rc != 0)
-            {
-                return rc;
-            }
-            rc = init_method(sel, data->top, g->isize);
-            if (rc != 0)
-            {
-                return rc;
-            }
+            _gmx_sel_evaluate_method_params(data, sel, g);
+            init_method(sel, data->top, g->isize);
             if (!(sel->flags & SEL_DYNAMIC))
             {
-                rc = sel->cdata->evaluate(data, sel, g);
-                if (rc == 0 && (sel->cdata->flags & SEL_CDATA_STATIC))
+                sel->cdata->evaluate(data, sel, g);
+                if (sel->cdata->flags & SEL_CDATA_STATIC)
                 {
                     make_static(sel);
                 }
@@ -2104,7 +2070,7 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
                  * maximum possible selections. */
                 if (sel->type == SEL_MODIFIER)
                 {
-                    rc = sel->cdata->evaluate(data, sel, g);
+                    sel->cdata->evaluate(data, sel, g);
                 }
                 if (bDoMinMax)
                 {
@@ -2116,8 +2082,8 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
         case SEL_BOOLEAN:
             if (!(sel->flags & SEL_DYNAMIC))
             {
-                rc = sel->cdata->evaluate(data, sel, g);
-                if (rc == 0 && (sel->cdata->flags & SEL_CDATA_STATIC))
+                sel->cdata->evaluate(data, sel, g);
+                if (sel->cdata->flags & SEL_CDATA_STATIC)
                 {
                     make_static(sel);
                 }
@@ -2125,11 +2091,7 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
             else
             {
                 /* Evalute the static part if there is more than one expression */
-                rc = evaluate_gmx_boolean_static_part(data, sel, g);
-                if (rc != 0)
-                {
-                    return rc;
-                }
+                evaluate_gmx_boolean_static_part(data, sel, g);
 
                 /* Evaluate the selection.
                  * If the type is gmx_boolean, we must explicitly handle the
@@ -2137,15 +2099,11 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
                  * here because g may be larger. */
                 if (sel->u.boolt == BOOL_AND && sel->child->type == SEL_CONST)
                 {
-                    rc = sel->cdata->evaluate(data, sel, sel->child->v.u.g);
+                    sel->cdata->evaluate(data, sel, sel->child->v.u.g);
                 }
                 else
                 {
-                    rc = sel->cdata->evaluate(data, sel, g);
-                }
-                if (rc != 0)
-                {
-                    return rc;
+                    sel->cdata->evaluate(data, sel, g);
                 }
 
                 /* Evaluate minimal and maximal selections */
@@ -2155,11 +2113,7 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
             break;
 
         case SEL_ARITHMETIC:
-            rc = sel->cdata->evaluate(data, sel, g);
-            if (rc != 0)
-            {
-                return rc;
-            }
+            sel->cdata->evaluate(data, sel, g);
             if (!(sel->flags & SEL_DYNAMIC))
             {
                 if (sel->cdata->flags & SEL_CDATA_STATIC)
@@ -2174,19 +2128,19 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
             break;
 
         case SEL_ROOT:
-            rc = sel->cdata->evaluate(data, sel, g);
+            sel->cdata->evaluate(data, sel, g);
             break;
 
         case SEL_SUBEXPR:
             if (sel->cdata->flags & (SEL_CDATA_SIMPLESUBEXPR | SEL_CDATA_FULLEVAL))
             {
-                rc = sel->cdata->evaluate(data, sel, g);
+                sel->cdata->evaluate(data, sel, g);
                 _gmx_selvalue_setstore(&sel->v, sel->child->v.u.ptr);
             }
             else if (sel->u.cgrp.isize == 0)
             {
                 gmx_ana_index_reserve(&sel->u.cgrp, g->isize);
-                rc = sel->cdata->evaluate(data, sel, g);
+                sel->cdata->evaluate(data, sel, g);
                 if (bDoMinMax)
                 {
                     gmx_ana_index_copy(sel->cdata->gmin, sel->child->cdata->gmin, TRUE);
@@ -2202,7 +2156,7 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
                     gmx_ana_index_reserve(&sel->u.cgrp, isize);
                     alloc_selection_data(sel, isize, FALSE);
                 }
-                rc = sel->cdata->evaluate(data, sel, g);
+                sel->cdata->evaluate(data, sel, g);
                 if (isize > 0 && bDoMinMax)
                 {
                     gmx_ana_index_reserve(sel->cdata->gmin,
@@ -2227,11 +2181,7 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
                  * selection). */
                 alloc_selection_data(sel, sel->child->cdata->gmax->isize, TRUE);
             }
-            rc = sel->cdata->evaluate(data, sel, g);
-            if (rc != 0)
-            {
-                return rc;
-            }
+            sel->cdata->evaluate(data, sel, g);
             if ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)
                 && (sel->child->child->flags & SEL_ALLOCVAL))
             {
@@ -2268,13 +2218,7 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
             break;
 
         case SEL_GROUPREF:
-            gmx_incons("unresolved group reference in compilation");
-            return -1;
-    }
-    /* Exit if there was some problem */
-    if (rc != 0)
-    {
-        return rc;
+            GMX_THROW(gmx::APIError("Unresolved group reference in compilation"));
     }
 
     /* Update the minimal and maximal evaluation groups */
@@ -2304,8 +2248,6 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
             gmx_ana_index_copy(sel->v.u.g, sel->cdata->gmin, FALSE);
         }
     }
-
-    return 0;
 }
 
 
@@ -2663,7 +2605,7 @@ calculate_mass_charge(std::vector<gmx::Selection *> *selections,
  * The covered fraction information in \p sc is initialized to
  * \ref CFRAC_NONE.
  */
-int
+void
 gmx_ana_selcollection_compile(gmx::SelectionCollection *coll)
 {
     gmx_ana_selcollection_t *sc = &coll->_impl->_sc;
@@ -2672,17 +2614,12 @@ gmx_ana_selcollection_compile(gmx::SelectionCollection *coll)
     e_poscalc_t  post;
     size_t       i;
     int          flags;
-    int          rc;
     bool         bDebug = (coll->_impl->_debugLevel >= 2
                            && coll->_impl->_debugLevel != 3);
 
     /* FIXME: Clean up the collection on exceptions */
 
-    rc = _gmx_sel_mempool_create(&sc->mempool);
-    if (rc != 0)
-    {
-        return rc;
-    }
+    sc->mempool = _gmx_sel_mempool_create();
     _gmx_sel_evaluate_init(&evaldata, sc->mempool, &sc->gall,
                            sc->top, NULL, NULL);
 
@@ -2763,12 +2700,7 @@ gmx_ana_selcollection_compile(gmx::SelectionCollection *coll)
             mark_subexpr_dynamic(item->child, TRUE);
         }
         set_evaluation_function(item, &analyze_static);
-        rc = item->evaluate(&evaldata, item, NULL);
-        if (rc != 0)
-        {
-            /* FIXME: Clean up the collection */
-            return rc;
-        }
+        item->evaluate(&evaldata, item, NULL);
         item = item->next;
     }
 
@@ -2788,7 +2720,7 @@ gmx_ana_selcollection_compile(gmx::SelectionCollection *coll)
     {
         if (item->child->cdata->flags & SEL_CDATA_COMMONSUBEXPR)
         {
-            gmx_bool bMinMax = item->child->cdata->flags & SEL_CDATA_MINMAXALLOC;
+            bool bMinMax = item->child->cdata->flags & SEL_CDATA_DOMINMAX;
 
             mark_subexpr_dynamic(item->child, FALSE);
             item->child->u.cgrp.isize = 0;
@@ -2802,16 +2734,11 @@ gmx_ana_selcollection_compile(gmx::SelectionCollection *coll)
              * For the same reason, we clear the min/max flag so that the
              * evaluation group doesn't get messed up. */
             set_evaluation_function(item, &analyze_static);
-            item->child->cdata->flags &= ~SEL_CDATA_MINMAXALLOC;
-            rc = item->evaluate(&evaldata, item->child, item->child->cdata->gmax);
+            item->child->cdata->flags &= ~SEL_CDATA_DOMINMAX;
+            item->evaluate(&evaldata, item->child, item->child->cdata->gmax);
             if (bMinMax)
             {
-                item->child->cdata->flags |= SEL_CDATA_MINMAXALLOC;
-            }
-            if (rc != 0)
-            {
-                /* FIXME: Clean up the collection */
-                return rc;
+                item->child->cdata->flags |= SEL_CDATA_DOMINMAX;
             }
         }
         item = item->next;
@@ -2844,14 +2771,8 @@ gmx_ana_selcollection_compile(gmx::SelectionCollection *coll)
     }
 
     /* Allocate memory for the evaluation memory pool. */
-    rc = _gmx_sel_mempool_reserve(sc->mempool, 0);
-    if (rc != 0)
-    {
-        return rc;
-    }
+    _gmx_sel_mempool_reserve(sc->mempool, 0);
 
     /* Finish up by calculating total masses and charges. */
     calculate_mass_charge(&sc->sel, sc->top);
-
-    return 0;
 }
index bc3e6984bf372890e424317c49126665fd7f6025..a74b916667e13dbf0454b9626b93b36bca58a573 100644 (file)
@@ -56,6 +56,8 @@
 #include <smalloc.h>
 #include <vec.h>
 
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
 #include "gromacs/selection/indexutil.h"
 #include "gromacs/selection/poscalc.h"
 #include "gromacs/selection/selection.h"
 #include "selectioncollection-impl.h"
 #include "selelem.h"
 
+/*! \internal \brief
+ * Reserves memory for a selection element from the evaluation memory pool.
+ */
+class MempoolSelelemReserver
+{
+    public:
+        MempoolSelelemReserver() : sel_(NULL) {}
+        MempoolSelelemReserver(t_selelem *sel, int count)
+            : sel_(NULL)
+        {
+            reserve(sel, count);
+        }
+        ~MempoolSelelemReserver()
+        {
+            if (sel_ != NULL)
+            {
+                _gmx_selelem_mempool_release(sel_);
+            }
+        }
+
+        void reserve(t_selelem *sel, int count)
+        {
+            GMX_RELEASE_ASSERT(sel_ == NULL, "Can only reserve one element with one instance");
+            _gmx_selelem_mempool_reserve(sel, count);
+            sel_ = sel;
+        }
+
+    private:
+        t_selelem              *sel_;
+};
+
+/*! \internal \brief
+ * Reserves memory for an index group from the evaluation memory pool.
+ */
+class MempoolGroupReserver
+{
+    public:
+        explicit MempoolGroupReserver(gmx_sel_mempool_t *mp)
+            : mp_(mp), g_(NULL)
+        {
+        }
+        ~MempoolGroupReserver()
+        {
+            if (g_ != NULL)
+            {
+                _gmx_sel_mempool_free_group(mp_, g_);
+            }
+        }
+
+        void reserve(gmx_ana_index_t *g, int count)
+        {
+            GMX_RELEASE_ASSERT(g_ == NULL, "Can only reserve one element with one instance");
+            _gmx_sel_mempool_alloc_group(mp_, g, count);
+            g_ = g;
+        }
+
+    private:
+        gmx_sel_mempool_t      *mp_;
+        gmx_ana_index_t        *g_;
+};
+
+/*! \internal \brief
+ * Assigns a temporary value for a selection element.
+ */
+class SelelemTemporaryValueAssigner
+{
+    public:
+        SelelemTemporaryValueAssigner()
+            : sel_(NULL), old_ptr_(NULL), old_nalloc_(0)
+        {
+        }
+        SelelemTemporaryValueAssigner(t_selelem *sel, t_selelem *vsource)
+            : sel_(NULL)
+        {
+            assign(sel, vsource);
+        }
+        ~SelelemTemporaryValueAssigner()
+        {
+            if (sel_ != NULL)
+            {
+                _gmx_selvalue_setstore_alloc(&sel_->v, old_ptr_, old_nalloc_);
+            }
+        }
+
+        void assign(t_selelem *sel, t_selelem *vsource)
+        {
+            GMX_RELEASE_ASSERT(sel_ == NULL, "Can only assign one element with one instance");
+            old_ptr_ = sel->v.u.ptr;
+            old_nalloc_ = sel->v.nalloc;
+            _gmx_selvalue_setstore(&sel->v, vsource->v.u.ptr);
+            sel_ = sel;
+        }
+
+    private:
+        t_selelem              *sel_;
+        void                   *old_ptr_;
+        int                     old_nalloc_;
+};
+
 /*!
  * \param[in] fp       File handle to receive the output.
  * \param[in] evalfunc Function pointer to print.
@@ -171,13 +272,12 @@ init_frame_eval(t_selelem *sel)
  * This is the only function that user code should call if they want to
  * evaluate a selection for a new frame.
  */
-int
+void
 gmx_ana_selcollection_evaluate(gmx_ana_selcollection_t *sc,
                                t_trxframe *fr, t_pbc *pbc)
 {
     gmx_sel_evaluate_t  data;
     t_selelem          *sel;
-    int                 rc;
 
     _gmx_sel_evaluate_init(&data, sc->mempool, &sc->gall, sc->top, fr, pbc);
     init_frame_eval(sc->root);
@@ -201,11 +301,7 @@ gmx_ana_selcollection_evaluate(gmx_ana_selcollection_t *sc,
         }
         if (sel->evaluate)
         {
-            rc = sel->evaluate(&data, sel, NULL);
-            if (rc != 0)
-            {
-                return rc;
-            }
+            sel->evaluate(&data, sel, NULL);
         }
         sel = sel->next;
     }
@@ -228,7 +324,6 @@ gmx_ana_selcollection_evaluate(gmx_ana_selcollection_t *sc,
             sel->avecfrac += sel->cfrac;
         }
     }
-    return 0;
 }
 
 /*!
@@ -268,27 +363,21 @@ gmx_ana_selcollection_evaluate_fin(gmx_ana_selcollection_t *sc, int nframes)
  *
  * Evaluates each child of \p sel in \p g.
  */
-int
+void
 _gmx_sel_evaluate_children(gmx_sel_evaluate_t *data, t_selelem *sel,
                            gmx_ana_index_t *g)
 {
     t_selelem  *child;
-    int         rc;
 
     child = sel->child;
     while (child)
     {
         if (child->evaluate)
         {
-            rc = child->evaluate(data, child, g);
-            if (rc != 0)
-            {
-                return rc;
-            }
+            child->evaluate(data, child, g);
         }
         child = child->next;
     }
-    return 0;
 }
 
 /*!
@@ -306,20 +395,16 @@ _gmx_sel_evaluate_children(gmx_sel_evaluate_t *data, t_selelem *sel,
  * This function can be used as \c t_selelem::evaluate for \ref SEL_ROOT
  * elements.
  */
-int
+void
 _gmx_sel_evaluate_root(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
-    int        rc;
-
     if (sel->u.cgrp.isize == 0 || !sel->child->evaluate)
     {
-        return 0;
+        return;
     }
 
-    rc = sel->child->evaluate(data, sel->child,
-                              sel->u.cgrp.isize < 0 ? NULL : &sel->u.cgrp);
-
-    return rc;
+    sel->child->evaluate(data, sel->child,
+                         sel->u.cgrp.isize < 0 ? NULL : &sel->u.cgrp);
 }
 
 /*!
@@ -333,11 +418,10 @@ _gmx_sel_evaluate_root(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t
  * This function can be used as \c t_selelem::evaluate for \ref SEL_CONST
  * elements with value type \ref GROUP_VALUE.
  */
-int
+void
 _gmx_sel_evaluate_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     gmx_ana_index_intersection(sel->v.u.g, &sel->u.cgrp, g);
-    return 0;
 }
 
 
@@ -359,21 +443,14 @@ _gmx_sel_evaluate_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index
  * elements that are used only once, and hence do not need full subexpression
  * handling.
  */
-int
+void
 _gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
-    int        rc;
-
     if (sel->child->evaluate)
     {
-        rc = sel->child->evaluate(data, sel->child, g);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        sel->child->evaluate(data, sel->child, g);
     }
     sel->v.nr = sel->child->v.nr;
-    return 0;
 }
 
 /*!
@@ -392,22 +469,15 @@ _gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_a
  * elements that have a static evaluation group, and hence do not need full
  * subexpression handling.
  */
-int
+void
 _gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     if (sel->u.cgrp.isize == 0)
     {
-        int  rc;
-
-        rc = sel->child->evaluate(data, sel->child, g);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        sel->child->evaluate(data, sel->child, g);
         sel->v.nr = sel->child->v.nr;
         gmx_ana_index_set(&sel->u.cgrp, g->isize, g->index, sel->u.cgrp.name, 0);
     }
-    return 0;
 }
 
 /*!
@@ -430,58 +500,35 @@ _gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *data, t_selelem *sel, g
  * _gmx_sel_evaluate_subexpr_staticeval() can be used, so this should not be a
  * major problem.
  */
-int
+void
 _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     gmx_ana_index_t  gmiss;
-    int              rc;
 
+    MempoolGroupReserver gmissreserver(data->mp);
     if (sel->u.cgrp.isize == 0)
     {
-        char *name;
-        void *old_ptr    = sel->child->v.u.ptr;
-        int   old_nalloc = sel->child->v.nalloc;
-        _gmx_selvalue_setstore(&sel->child->v, sel->v.u.ptr);
-        rc = sel->child->evaluate(data, sel->child, g);
-        _gmx_selvalue_setstore_alloc(&sel->child->v, old_ptr, old_nalloc);
-        if (rc != 0)
         {
-            return rc;
+            SelelemTemporaryValueAssigner assigner(sel->child, sel);
+            sel->child->evaluate(data, sel->child, g);
         }
         /* We need to keep the name for the cgrp across the copy to avoid
          * problems if g has a name set. */
-        name = sel->u.cgrp.name;
+        char *name = sel->u.cgrp.name;
         gmx_ana_index_copy(&sel->u.cgrp, g, FALSE);
         sel->u.cgrp.name = name;
         gmiss.isize = 0;
     }
     else
     {
-        /* We allocate some extra memory here to avoid some computation. */
-        rc = _gmx_sel_mempool_alloc_group(data->mp, &gmiss, g->isize);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        gmissreserver.reserve(&gmiss, g->isize);
         gmx_ana_index_difference(&gmiss, g, &sel->u.cgrp);
-        if (gmiss.isize == 0)
-        {
-            _gmx_sel_mempool_free_group(data->mp, &gmiss);
-        }
     }
     if (gmiss.isize > 0)
     {
-        rc = _gmx_selelem_mempool_reserve(sel->child, gmiss.isize);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        MempoolSelelemReserver reserver(sel->child, gmiss.isize);
         /* Evaluate the missing values for the child */
-        rc = sel->child->evaluate(data, sel->child, &gmiss);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        sel->child->evaluate(data, sel->child, &gmiss);
         /* Merge the missing values to the existing ones. */
         if (sel->v.type == GROUP_VALUE)
         {
@@ -541,20 +588,15 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_inde
 
                 case POS_VALUE:
                     /* TODO: Implement this */
-                    gmx_impl("position subexpressions not implemented properly");
-                    return -1;
+                    GMX_THROW(gmx::NotImplementedError("position subexpressions not implemented properly"));
 
                 case NO_VALUE:
                 case GROUP_VALUE:
-                    gmx_bug("internal error");
-                    return -1;
+                    GMX_THROW(gmx::InternalError("Invalid subexpression type"));
             }
         }
         gmx_ana_index_merge(&sel->u.cgrp, &sel->u.cgrp, &gmiss);
-        _gmx_selelem_mempool_release(sel->child);
-        _gmx_sel_mempool_free_group(data->mp, &gmiss);
     }
-    return 0;
 }
 
 /*!
@@ -570,21 +612,15 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_inde
  * This function is used as \c t_selelem:evaluate for \ref SEL_SUBEXPRREF
  * elements for which the \ref SEL_SUBEXPR does not have other references.
  */
-int
+void
 _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     if (g)
     {
-        int rc;
-
         _gmx_selvalue_setstore(&sel->child->v, sel->v.u.ptr);
         _gmx_selvalue_setstore_alloc(&sel->child->child->v, sel->v.u.ptr,
                                      sel->child->child->v.nalloc);
-        rc = sel->child->evaluate(data, sel->child, g);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        sel->child->evaluate(data, sel->child, g);
     }
     sel->v.nr = sel->child->v.nr;
     if (sel->u.param)
@@ -595,7 +631,6 @@ _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data, t_selelem *sel, gm
             *sel->u.param->nvalptr = sel->u.param->val.nr;
         }
     }
-    return 0;
 }
 
 /*!
@@ -614,7 +649,7 @@ _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data, t_selelem *sel, gm
  * This function is used as \c t_selelem::evaluate for \ref SEL_SUBEXPRREF
  * elements.
  */
-int
+void
 _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     t_selelem *expr;
@@ -622,13 +657,7 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_i
 
     if (g)
     {
-        int rc;
-
-        rc = sel->child->evaluate(data, sel->child, g);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        sel->child->evaluate(data, sel->child, g);
     }
     expr = sel->child;
     switch (sel->v.type)
@@ -715,8 +744,7 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_i
             break;
 
         default: /* should not be reached */
-            gmx_bug("invalid subexpression reference type");
-            return -1;
+            GMX_THROW(gmx::InternalError("Invalid subexpression reference type"));
     }
     /* Store the number of values if needed */
     if (sel->u.param)
@@ -727,7 +755,6 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_i
             *sel->u.param->nvalptr = sel->u.param->val.nr;
         }
     }
-    return 0;
 }
 
 /********************************************************************
@@ -746,11 +773,10 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_i
  * This function is not used as \c t_selelem::evaluate,
  * but is used internally.
  */
-int
+void
 _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     t_selelem *child;
-    int        rc;
 
     child = sel->child;
     while (child)
@@ -759,21 +785,16 @@ _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_an
         {
             if (child->flags & SEL_ATOMVAL)
             {
-                rc = child->evaluate(data, child, g);
+                child->evaluate(data, child, g);
             }
             else
             {
-                rc = child->evaluate(data, child, NULL);
                 child->flags |= SEL_EVALFRAME;
-            }
-            if (rc != 0)
-            {
-                return rc;
+                child->evaluate(data, child, NULL);
             }
         }
         child = child->next;
     }
-    return 0;
 }
 
 /*!
@@ -793,40 +814,29 @@ _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_an
  * This function is used as \c t_selelem::evaluate for \ref SEL_EXPRESSION
  * elements.
  */
-int
+void
 _gmx_sel_evaluate_method(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
-    int rc;
-
-    rc = _gmx_sel_evaluate_method_params(data, sel, g);
-    if (rc != 0)
-    {
-        return rc;
-    }
+    _gmx_sel_evaluate_method_params(data, sel, g);
     if (sel->flags & SEL_INITFRAME)
     {
-        rc = sel->u.expr.method->init_frame(data->top, data->fr, data->pbc,
-                                            sel->u.expr.mdata);
         sel->flags &= ~SEL_INITFRAME;
-        if (rc != 0)
-        {
-            return rc;
-        }
+        sel->u.expr.method->init_frame(data->top, data->fr, data->pbc,
+                                       sel->u.expr.mdata);
     }
     if (sel->u.expr.pc)
     {
         gmx_ana_poscalc_update(sel->u.expr.pc, sel->u.expr.pos, g,
                                data->fr, data->pbc);
-        rc = sel->u.expr.method->pupdate(data->top, data->fr, data->pbc,
-                                         sel->u.expr.pos, &sel->v,
-                                         sel->u.expr.mdata);
+        sel->u.expr.method->pupdate(data->top, data->fr, data->pbc,
+                                    sel->u.expr.pos, &sel->v,
+                                    sel->u.expr.mdata);
     }
     else
     {
-        rc = sel->u.expr.method->update(data->top, data->fr, data->pbc, g,
-                                        &sel->v, sel->u.expr.mdata);
+        sel->u.expr.method->update(data->top, data->fr, data->pbc, g,
+                                   &sel->v, sel->u.expr.mdata);
     }
-    return rc;
 }
 
 /*!
@@ -844,35 +854,23 @@ _gmx_sel_evaluate_method(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index
  * This function is used as \c t_selelem::evaluate for \ref SEL_MODIFIER
  * elements.
  */
-int
+void
 _gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
-    int rc;
-
-    rc = _gmx_sel_evaluate_method_params(data, sel, g);
-    if (rc != 0)
-    {
-        return rc;
-    }
+    _gmx_sel_evaluate_method_params(data, sel, g);
     if (sel->flags & SEL_INITFRAME)
     {
-        rc = sel->u.expr.method->init_frame(data->top, data->fr, data->pbc,
-                                            sel->u.expr.mdata);
         sel->flags &= ~SEL_INITFRAME;
-        if (rc != 0)
-        {
-            return rc;
-        }
+        sel->u.expr.method->init_frame(data->top, data->fr, data->pbc,
+                                            sel->u.expr.mdata);
     }
     if (sel->child->v.type != POS_VALUE)
     {
-        gmx_bug("non-position valued modifiers not implemented");
-        return -1;
+        GMX_THROW(gmx::NotImplementedError("Non-position valued modifiers not implemented"));
     }
-    rc = sel->u.expr.method->pupdate(data->top, data->fr, data->pbc,
-                                    sel->child->v.u.p,
-                                    &sel->v, sel->u.expr.mdata);
-    return rc;
+    sel->u.expr.method->pupdate(data->top, data->fr, data->pbc,
+                                sel->child->v.u.p,
+                                &sel->v, sel->u.expr.mdata);
 }
 
 
@@ -893,23 +891,12 @@ _gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_ind
  * This function is used as \c t_selelem::evaluate for \ref SEL_BOOLEAN
  * elements with \ref BOOL_NOT.
  */
-int
+void
 _gmx_sel_evaluate_not(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
-    int rc;
-
-    rc = _gmx_selelem_mempool_reserve(sel->child, g->isize);
-    if (rc == 0)
-    {
-        rc = sel->child->evaluate(data, sel->child, g);
-    }
-    if (rc != 0)
-    {
-        return rc;
-    }
+    MempoolSelelemReserver reserver(sel->child, g->isize);
+    sel->child->evaluate(data, sel->child, g);
     gmx_ana_index_difference(sel->v.u.g, g, sel->child->v.u.g);
-    _gmx_selelem_mempool_release(sel->child);
-    return 0;
 }
 
 /*!
@@ -937,11 +924,10 @@ _gmx_sel_evaluate_not(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t
  * This function is used as \c t_selelem::evaluate for \ref SEL_BOOLEAN
  * elements with \ref BOOL_AND.
  */
-int
+void
 _gmx_sel_evaluate_and(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     t_selelem *child;
-    int        rc;
 
     child = sel->child;
     /* Skip the first child if it does not have an evaluation function. */
@@ -949,34 +935,20 @@ _gmx_sel_evaluate_and(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t
     {
         child = child->next;
     }
-    rc = _gmx_selelem_mempool_reserve(child, g->isize);
-    if (rc == 0)
-    {
-        rc = child->evaluate(data, child, g);
-    }
-    if (rc != 0)
+    /* Evaluate the first child */
     {
-        return rc;
+        MempoolSelelemReserver reserver(child, g->isize);
+        child->evaluate(data, child, g);
+        gmx_ana_index_copy(sel->v.u.g, child->v.u.g, FALSE);
     }
-    gmx_ana_index_copy(sel->v.u.g, child->v.u.g, FALSE);
-    _gmx_selelem_mempool_release(child);
     child = child->next;
     while (child && sel->v.u.g->isize > 0)
     {
-        rc = _gmx_selelem_mempool_reserve(child, sel->v.u.g->isize);
-        if (rc == 0)
-        {
-            rc = child->evaluate(data, child, sel->v.u.g);
-        }
-        if (rc != 0)
-        {
-            return rc;
-        }
+        MempoolSelelemReserver reserver(child, sel->v.u.g->isize);
+        child->evaluate(data, child, sel->v.u.g);
         gmx_ana_index_intersection(sel->v.u.g, sel->v.u.g, child->v.u.g);
-        _gmx_selelem_mempool_release(child);
         child = child->next;
     }
-    return 0;
 }
 
 /*!
@@ -1005,27 +977,18 @@ _gmx_sel_evaluate_and(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t
  * This function is used as \c t_selelem::evaluate for \ref SEL_BOOLEAN
  * elements with \ref BOOL_OR.
  */
-int
+void
 _gmx_sel_evaluate_or(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
 {
     t_selelem     *child;
     gmx_ana_index_t  tmp, tmp2;
-    int              rc;
 
     child = sel->child;
     if (child->evaluate)
     {
-        rc = _gmx_selelem_mempool_reserve(child, g->isize);
-        if (rc == 0)
-        {
-            rc = child->evaluate(data, child, g);
-        }
-        if (rc != 0)
-        {
-            return rc;
-        }
+        MempoolSelelemReserver reserver(child, g->isize);
+        child->evaluate(data, child, g);
         gmx_ana_index_partition(sel->v.u.g, &tmp, g, child->v.u.g);
-        _gmx_selelem_mempool_release(child);
     }
     else
     {
@@ -1035,24 +998,17 @@ _gmx_sel_evaluate_or(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *
     while (child && tmp.isize > 0)
     {
         tmp.name = NULL;
-        rc = _gmx_selelem_mempool_reserve(child, tmp.isize);
-        if (rc == 0)
-        {
-            rc = child->evaluate(data, child, &tmp);
-        }
-        if (rc != 0)
         {
-            return rc;
+            MempoolSelelemReserver reserver(child, tmp.isize);
+            child->evaluate(data, child, &tmp);
+            gmx_ana_index_partition(&tmp, &tmp2, &tmp, child->v.u.g);
         }
-        gmx_ana_index_partition(&tmp, &tmp2, &tmp, child->v.u.g);
-        _gmx_selelem_mempool_release(child);
         sel->v.u.g->isize += tmp.isize;
         tmp.isize = tmp2.isize;
         tmp.index = tmp2.index;
         child = child->next;
     }
     gmx_ana_index_sort(sel->v.u.g);
-    return 0;
 }
 
 
@@ -1066,35 +1022,32 @@ _gmx_sel_evaluate_or(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *
  * \param[in] g    Group for which \p sel should be evaluated.
  * \returns   0 on success, a non-zero error code on error.
  */
-int
+void
 _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, t_selelem *sel,
                              gmx_ana_index_t *g)
 {
     t_selelem  *left, *right;
     int         n, i, i1, i2;
     real        lval, rval=0., val=0.;
-    int         rc;
 
     left  = sel->child;
     right = left->next;
 
+    SelelemTemporaryValueAssigner assigner;
+    MempoolSelelemReserver reserver;
     if (left->mempool)
     {
-        _gmx_selvalue_setstore(&left->v, sel->v.u.ptr);
+        assigner.assign(left, sel);
         if (right)
         {
-            rc = _gmx_selelem_mempool_reserve(right, g->isize);
-            if (rc != 0)
-            {
-                return rc;
-            }
+            reserver.reserve(right, g->isize);
         }
     }
     else if (right && right->mempool)
     {
-        _gmx_selvalue_setstore(&right->v, sel->v.u.ptr);
+        assigner.assign(right, sel);
     }
-    rc = _gmx_sel_evaluate_children(data, sel, g);
+    _gmx_sel_evaluate_children(data, sel, g);
 
     n = (sel->flags & SEL_SINGLEVAL) ? 1 : g->isize;
     sel->v.nr = n;
@@ -1124,18 +1077,4 @@ _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, t_selelem *sel,
             ++i2;
         }
     }
-
-    if (left->mempool)
-    {
-        _gmx_selvalue_setstore(&left->v, NULL);
-        if (right)
-        {
-            _gmx_selelem_mempool_release(right);
-        }
-    }
-    else if (right && right->mempool)
-    {
-        _gmx_selvalue_setstore(&right->v, NULL);
-    }
-    return 0;
 }
index d0c25df2e5f667a0d6f31ca86ca3e1b4542db72a..3947e434e58c9f28f60a5a997d895085330bca9d 100644 (file)
@@ -79,10 +79,10 @@ _gmx_sel_evaluate_init(gmx_sel_evaluate_t *data,
                        struct gmx_sel_mempool_t *mp, gmx_ana_index_t *gall,
                        t_topology *top, t_trxframe *fr, t_pbc *pbc);
 /** Evaluates the children of a general selection element. */
-int
+void
 _gmx_sel_evaluate_children(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates the children of a \ref SEL_EXPRESSION element. */
-int
+void
 _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /*@}*/
 
@@ -90,13 +90,13 @@ _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_an
  */
 /*@{*/
 /** Evaluates a root selection element. */
-int
+void
 _gmx_sel_evaluate_root(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates a static group selection element. */
-int
+void
 _gmx_sel_evaluate_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates an arithmetic expression element. */
-int
+void
 _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /*@}*/
 
@@ -104,19 +104,19 @@ _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_i
  */
 /*@{*/
 /** Evaluates a subexpression when there is only one reference. */
-int
+void
 _gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates a subexpression when the evaluation group is static. */
-int
+void
 _gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates a subexpression. */
-int
+void
 _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates a subexpression reference when there are no other references. */
-int
+void
 _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates a subexpression reference. */
-int
+void
 _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /*@}*/
 
@@ -125,10 +125,10 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_i
 /*@{*/
 
 /** Evaluates a method expression. */
-int
+void
 _gmx_sel_evaluate_method(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates a modifier expression. */
-int
+void
 _gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /*@}*/
 
@@ -136,13 +136,13 @@ _gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_ind
  */
 /*@{*/
 /** Evaluates a boolean NOT element. */
-int
+void
 _gmx_sel_evaluate_not(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates a boolean AND element with short-circuiting. */
-int
+void
 _gmx_sel_evaluate_and(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /** Evaluates a boolean OR element with short-circuiting. */
-int
+void
 _gmx_sel_evaluate_or(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g);
 /*@}*/
 
index 74a04cf3a1e69d2aaeda6f84351bd739fd9b3519..e6a1fec306594963c3231dbd8edd9aa2ee016db2 100644 (file)
 #include <config.h>
 #endif
 
-#include <assert.h>
 #include <stdlib.h>
 
-#include <gmx_fatal.h>
+#include <new>
+
 #include <smalloc.h>
 
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
 #include "gromacs/selection/indexutil.h"
 
 #include "mempool.h"
@@ -89,8 +91,8 @@ struct gmx_sel_mempool_t
     size_t                      maxsize;
 };
 
-int
-_gmx_sel_mempool_create(gmx_sel_mempool_t **mpp)
+gmx_sel_mempool_t *
+_gmx_sel_mempool_create()
 {
     gmx_sel_mempool_t *mp;
 
@@ -103,8 +105,7 @@ _gmx_sel_mempool_create(gmx_sel_mempool_t **mpp)
     mp->blockstack        = NULL;
     mp->blockstack_nalloc = 0;
     mp->maxsize           = 0;
-    *mpp = mp;
-    return 0;
+    return mp;
 }
 
 void
@@ -124,20 +125,18 @@ _gmx_sel_mempool_destroy(gmx_sel_mempool_t *mp)
     sfree(mp);
 }
 
-int
-_gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, void **ptrp, size_t size)
+void *
+_gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, size_t size)
 {
     void   *ptr = NULL;
     size_t  size_walign;
 
-    *ptrp = NULL;
     size_walign = ((size + ALIGN_STEP - 1) / ALIGN_STEP) * ALIGN_STEP;
     if (mp->buffer)
     {
         if (mp->freesize < size)
         {
-            gmx_bug("out of memory pool memory");
-            return ENOMEM;
+            GMX_THROW(gmx::InternalError("Out of memory pool memory"));
         }
         ptr = mp->freeptr;
         mp->freeptr  += size_walign;
@@ -149,8 +148,7 @@ _gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, void **ptrp, size_t size)
         ptr = malloc(size);
         if (!ptr)
         {
-            gmx_mem("out of memory");
-            return ENOMEM;
+            throw std::bad_alloc();
         }
         mp->currsize += size_walign;
         if (mp->currsize > mp->maxsize)
@@ -168,8 +166,7 @@ _gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, void **ptrp, size_t size)
     mp->blockstack[mp->nblocks].size = size_walign;
     mp->nblocks++;
 
-    *ptrp = ptr;
-    return 0;
+    return ptr;
 }
 
 void
@@ -181,7 +178,8 @@ _gmx_sel_mempool_free(gmx_sel_mempool_t *mp, void *ptr)
     {
         return;
     }
-    assert(mp->nblocks > 0 && mp->blockstack[mp->nblocks - 1].ptr == ptr);
+    GMX_RELEASE_ASSERT(mp->nblocks > 0 && mp->blockstack[mp->nblocks - 1].ptr == ptr,
+                       "Invalid order of memory pool free calls");
     mp->nblocks--;
     size = mp->blockstack[mp->nblocks].size;
     mp->currsize -= size;
@@ -196,10 +194,12 @@ _gmx_sel_mempool_free(gmx_sel_mempool_t *mp, void *ptr)
     }
 }
 
-int
+void
 _gmx_sel_mempool_reserve(gmx_sel_mempool_t *mp, size_t size)
 {
-    assert(mp->nblocks == 0 && !mp->buffer);
+    GMX_RELEASE_ASSERT(mp->nblocks == 0,
+                       "Cannot reserve memory pool when there is something allocated");
+    GMX_RELEASE_ASSERT(!mp->buffer, "Cannot reserve memory pool twice");
     if (size == 0)
     {
         size = mp->maxsize;
@@ -207,20 +207,18 @@ _gmx_sel_mempool_reserve(gmx_sel_mempool_t *mp, size_t size)
     mp->buffer = (char *)malloc(size);
     if (!mp->buffer)
     {
-        gmx_mem("out of memory");
-        return ENOMEM;
+        throw std::bad_alloc();
     }
     mp->freesize = size;
     mp->freeptr  = mp->buffer;
-    return 0;
 }
 
-int
+void
 _gmx_sel_mempool_alloc_group(gmx_sel_mempool_t *mp, gmx_ana_index_t *g,
                              int isize)
 {
-    return _gmx_sel_mempool_alloc(mp, (void **)&g->index,
-                                  sizeof(*g->index)*isize);
+    void *ptr = _gmx_sel_mempool_alloc(mp, sizeof(*g->index)*isize);
+    g->index = static_cast<int *>(ptr);
 }
 
 void
index dfaa81a13c12ff81ff94d8668cfff378f11a8f9b..7a6305bf83ddfe135645609a6932c5f46fc775e5 100644 (file)
@@ -49,24 +49,24 @@ struct gmx_ana_index_t;
 typedef struct gmx_sel_mempool_t gmx_sel_mempool_t;
 
 /** Create an empty memory pool. */
-int
-_gmx_sel_mempool_create(gmx_sel_mempool_t **mpp);
+gmx_sel_mempool_t *
+_gmx_sel_mempool_create();
 /** Destroy a memory pool. */
 void
 _gmx_sel_mempool_destroy(gmx_sel_mempool_t *mp);
 
 /** Allocate memory from a memory pool. */
-int
-_gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, void **ptrp, size_t size);
+void *
+_gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, size_t size);
 /** Release memory allocated from a memory pool. */
 void
 _gmx_sel_mempool_free(gmx_sel_mempool_t *mp, void *ptr);
 /** Set the size of a memory pool. */
-int
+void
 _gmx_sel_mempool_reserve(gmx_sel_mempool_t *mp, size_t size);
 
 /** Convenience function for allocating an index group from a memory pool. */
-int
+void
 _gmx_sel_mempool_alloc_group(gmx_sel_mempool_t *mp, struct gmx_ana_index_t *g,
                              int isize);
 /** Convenience function for freeing an index group from a memory pool. */
index 1d59e0b972db23f5a1ba384985900baea6ea667c..6ac475654202846b0fc21acb446160c8e7df7976 100644 (file)
@@ -152,17 +152,16 @@ struct gmx_ana_nbsearch_t
 };
 
 /*!
- * \param[out] data   Neighborhood search data structure pointer to initialize.
  * \param[in]  cutoff Cutoff distance for the search
  *   (<=0 stands for no cutoff).
  * \param[in]  maxn   Maximum number of reference particles.
- * \returns    0 on success.
+ * \returns  Created neighborhood search data structure.
  */
-int
-gmx_ana_nbsearch_create(gmx_ana_nbsearch_t **data, real cutoff, int maxn)
+gmx_ana_nbsearch_t *
+gmx_ana_nbsearch_create(real cutoff, int maxn)
 {
     gmx_ana_nbsearch_t *d;
-    
+
     snew(d, 1);
     d->bTryGrid = TRUE;
     if (cutoff <= 0)
@@ -189,8 +188,7 @@ gmx_ana_nbsearch_create(gmx_ana_nbsearch_t **data, real cutoff, int maxn)
     d->gnboffs = NULL;
     d->gnboffs_nalloc = 0;
 
-    *data = d;
-    return 0;
+    return d;
 }
 
 /*!
@@ -446,12 +444,11 @@ grid_add_to_cell(gmx_ana_nbsearch_t *d, const ivec cell, int i)
  * \param[in]     pbc PBC information for the frame.
  * \param[in]     n   Number of reference positions for the frame.
  * \param[in]     x   \p n reference positions for the frame.
- * \returns       0 on success.
  *
  * Initializes the data structure \p d such that it can be used to search
  * for the neighbors of \p x.
  */
-int
+void
 gmx_ana_nbsearch_init(gmx_ana_nbsearch_t *d, t_pbc *pbc, int n, const rvec x[])
 {
     d->pbc  = pbc;
@@ -495,25 +492,20 @@ gmx_ana_nbsearch_init(gmx_ana_nbsearch_t *d, t_pbc *pbc, int n, const rvec x[])
         d->xref = const_cast<rvec *>(x);
     }
     d->refid = NULL;
-    return 0;
 }
 
 /*!
  * \param[in,out] d   Neighborhood search data structure.
  * \param[in]     pbc PBC information for the frame.
  * \param[in]     p   Reference positions for the frame.
- * \returns       0 on success.
  *
  * A convenience wrapper for gmx_ana_nbsearch_init().
  */
-int
+void
 gmx_ana_nbsearch_pos_init(gmx_ana_nbsearch_t *d, t_pbc *pbc, const gmx_ana_pos_t *p)
 {
-    int rc;
-
-    rc = gmx_ana_nbsearch_init(d, pbc, p->nr, p->x);
+    gmx_ana_nbsearch_init(d, pbc, p->nr, p->x);
     d->refid = (p->nr < d->maxnref ? p->m.refid : NULL);
-    return rc;
 }
 
 /*!
@@ -521,17 +513,15 @@ gmx_ana_nbsearch_pos_init(gmx_ana_nbsearch_t *d, t_pbc *pbc, const gmx_ana_pos_t
  * \param[in]     nexcl Number of reference positions to exclude from next
  *      search.
  * \param[in]     excl  Indices of reference positions to exclude.
- * \returns       0 on success.
  *
  * The set exclusions remain in effect until the next call of this function.
  */
-int
+void
 gmx_ana_nbsearch_set_excl(gmx_ana_nbsearch_t *d, int nexcl, int excl[])
 {
 
     d->nexcl = nexcl;
     d->excl = excl;
-    return 0;
 }
 
 /*! \brief
index cd59792c41c8921e1a93f4766b31eabeaeb95e12..0e671fce7e64a4eda1d0e0770e6f34ec549efd65 100644 (file)
 
 #include "indexutil.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 struct gmx_ana_pos_t;
 
 /** Data structure for neighborhood searches. */
 typedef struct gmx_ana_nbsearch_t gmx_ana_nbsearch_t;
 
 /** Create a new neighborhood search data structure. */
-int
-gmx_ana_nbsearch_create(gmx_ana_nbsearch_t **d, real cutoff, int maxn);
+gmx_ana_nbsearch_t *
+gmx_ana_nbsearch_create(real cutoff, int maxn);
 /** Free memory allocated for neighborhood search. */
 void
 gmx_ana_nbsearch_free(gmx_ana_nbsearch_t *d);
 
 /** Initializes neighborhood search for a new frame. */
-int
+void
 gmx_ana_nbsearch_init(gmx_ana_nbsearch_t *d, t_pbc *pbc, int n, const rvec x[]);
 /** Initializes neighborhood search for a frame using \c gmx_ana_pos_t.  */
-int
+void
 gmx_ana_nbsearch_pos_init(gmx_ana_nbsearch_t *d, t_pbc *pbc,
                           const struct gmx_ana_pos_t *p);
 /** Sets the exclusions for the next neighborhood search. */
-int
+void
 gmx_ana_nbsearch_set_excl(gmx_ana_nbsearch_t *d, int nexcl, int excl[]);
 /** Check whether a point is within a neighborhood. */
 gmx_bool
@@ -99,8 +95,4 @@ gmx_ana_nbsearch_pos_first_within(gmx_ana_nbsearch_t *d,
 gmx_bool
 gmx_ana_nbsearch_next_within(gmx_ana_nbsearch_t *d, int *jp);
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif
index f30414f905cf84e571d3b3e97a55aed614612f35..acf7d91e77ef47a2a4a5c465f0888c92beefad6e 100644 (file)
@@ -191,14 +191,14 @@ class SelectionCollection::Impl
 /*! \internal \brief
  * Prepares the selections for evaluation and performs some optimizations.
  */
-int
+void
 gmx_ana_selcollection_compile(gmx::SelectionCollection *coll);
 
 /* In evaluate.cpp */
 /*! \internal \brief
  * Evaluates the selection.
  */
-int
+void
 gmx_ana_selcollection_evaluate(gmx_ana_selcollection_t *sc,
                                t_trxframe *fr, t_pbc *pbc);
 /*! \internal \brief
index 4ffe60403560bdbc203102288ca9c420596d78d6..fb8de2caf83a9f9e28b0f0a07a3bdf3a462dabce 100644 (file)
@@ -562,7 +562,7 @@ SelectionCollection::parseFromString(const std::string &str,
 }
 
 
-int
+void
 SelectionCollection::compile()
 {
     if (!_impl->hasFlag(Impl::efExternalGroupsSet))
@@ -573,8 +573,8 @@ SelectionCollection::compile()
     {
         printTree(stderr, false);
     }
-    int rc = gmx_ana_selcollection_compile(this);
-    if (rc == 0 && _impl->hasFlag(Impl::efOwnPositionCollection))
+    gmx_ana_selcollection_compile(this);
+    if (_impl->hasFlag(Impl::efOwnPositionCollection))
     {
         if (_impl->_debugLevel >= 1)
         {
@@ -591,24 +591,22 @@ SelectionCollection::compile()
             std::fprintf(stderr, "\n");
         }
     }
-    return rc;
 }
 
 
-int
+void
 SelectionCollection::evaluate(t_trxframe *fr, t_pbc *pbc)
 {
     if (_impl->hasFlag(Impl::efOwnPositionCollection))
     {
         gmx_ana_poscalc_init_frame(_impl->_sc.pcc);
     }
-    int rc = gmx_ana_selcollection_evaluate(&_impl->_sc, fr, pbc);
-    if (rc == 0 && _impl->_debugLevel >= 3)
+    gmx_ana_selcollection_evaluate(&_impl->_sc, fr, pbc);
+    if (_impl->_debugLevel >= 3)
     {
         std::fprintf(stderr, "\n");
         printTree(stderr, true);
     }
-    return rc;
 }
 
 
index f7528e532f7fd70983e52b239e6e601e2eaa5a58..e1d67d209767c173e29f104ac3622fa0871877ab 100644 (file)
@@ -264,7 +264,7 @@ class SelectionCollection
          * The covered fraction information is initialized to ::CFRAC_NONE for
          * all selections.
          */
-        int compile();
+        void compile();
         /*! \brief
          * Evaluates selections in the collection.
          *
@@ -272,7 +272,7 @@ class SelectionCollection
          * \param[in] pbc PBC data, or NULL if no PBC should be used.
          * \returns   0 on successful evaluation, a non-zero error code on error.
          */
-        int evaluate(t_trxframe *fr, t_pbc *pbc);
+        void evaluate(t_trxframe *fr, t_pbc *pbc);
         /*! \brief
          * Evaluates the largest possible index groups from dynamic selections.
          *
index 639393749b0ef39e180940f60219ca7c14f42213..d675711401770b882ee61aeb01f49a3e77dbadee 100644 (file)
@@ -42,6 +42,7 @@
 #include <smalloc.h>
 #include <gmx_fatal.h>
 
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/indexutil.h"
 #include "gromacs/selection/poscalc.h"
 #include "gromacs/selection/position.h"
@@ -193,36 +194,32 @@ _gmx_selelem_set_vtype(t_selelem *sel, e_selvalue_t vtype)
  * Reserves memory for the values of \p sel from the \p sel->mempool
  * memory pool. If no memory pool is set, nothing is done.
  */
-int
+void
 _gmx_selelem_mempool_reserve(t_selelem *sel, int count)
 {
-    int rc = 0;
-
     if (!sel->mempool)
     {
-        return 0;
+        return;
     }
     switch (sel->v.type)
     {
         case INT_VALUE:
-            rc = _gmx_sel_mempool_alloc(sel->mempool, (void **)&sel->v.u.i,
-                                        sizeof(*sel->v.u.i)*count);
+            sel->v.u.i = static_cast<int *>(
+                    _gmx_sel_mempool_alloc(sel->mempool, sizeof(*sel->v.u.i)*count));
             break;
 
         case REAL_VALUE:
-            rc = _gmx_sel_mempool_alloc(sel->mempool, (void **)&sel->v.u.r,
-                                        sizeof(*sel->v.u.r)*count);
+            sel->v.u.r = static_cast<real *>(
+                    _gmx_sel_mempool_alloc(sel->mempool, sizeof(*sel->v.u.r)*count));
             break;
 
         case GROUP_VALUE:
-            rc = _gmx_sel_mempool_alloc_group(sel->mempool, sel->v.u.g, count);
+            _gmx_sel_mempool_alloc_group(sel->mempool, sel->v.u.g, count);
             break;
 
         default:
-            gmx_incons("mem pooling not implemented for requested type");
-            return -1;
+            GMX_THROW(gmx::InternalError("Memory pooling not implemented for requested type"));
     }
-    return rc;
 }
 
 /*!
@@ -254,8 +251,7 @@ _gmx_selelem_mempool_release(t_selelem *sel)
             break;
 
         default:
-            gmx_incons("mem pooling not implemented for requested type");
-            break;
+            GMX_THROW(gmx::InternalError("Memory pooling not implemented for requested type"));
     }
 }
 
index 9740aa86348d358c0bd4edab01710a71d3a4efc9..bc30cfd47e5c82a5a20dd912006f0f868af3ed15 100644 (file)
@@ -222,8 +222,8 @@ struct t_selelem;
 /*! \brief
  * Function pointer for evaluating a \c t_selelem.
  */
-typedef int (*sel_evalfunc)(struct gmx_sel_evaluate_t *data,
-                            struct t_selelem *sel, gmx_ana_index_t *g);
+typedef void (*sel_evalfunc)(struct gmx_sel_evaluate_t *data,
+                             struct t_selelem *sel, gmx_ana_index_t *g);
 
 /*! \internal \brief
  * Represents an element of a selection expression.
@@ -333,7 +333,7 @@ _gmx_selelem_create(e_selelem_t type);
 extern int
 _gmx_selelem_set_vtype(t_selelem *sel, e_selvalue_t vtype);
 /** Reserves memory for value of a \c t_selelem from a memory pool. */
-extern int
+extern void
 _gmx_selelem_mempool_reserve(t_selelem *sel, int count);
 /** Releases memory pool used for value of a \c t_selelem. */
 extern void
index 0e08994569993222e8ed22ec1678d32ecf2a0618..f5290a0d4beea3c7656f760db07d140208361339 100644 (file)
 #include "selparam.h"
 #include "selvalue.h"
 
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
 struct gmx_ana_pos_t;
 struct gmx_ana_poscalc_coll_t;
 struct gmx_ana_selcollection_t;
@@ -439,7 +434,7 @@ typedef void  (*sel_posfunc)(struct gmx_ana_poscalc_coll_t *pcc, void *data);
  * This function may be called multiple times for the same method if the
  * method takes parameters with \ref SPAR_ATOMVAL set.
  */
-typedef int   (*sel_initfunc)(t_topology *top, int npar,
+typedef void  (*sel_initfunc)(t_topology *top, int npar,
                               gmx_ana_selparam_t *param, void *data);
 /*! \brief
  * Initializes output data structure.
@@ -468,7 +463,7 @@ typedef int   (*sel_initfunc)(t_topology *top, int npar,
  * This function may be called multiple times for the same method if the
  * method takes parameters with \ref SPAR_ATOMVAL set.
  */
-typedef int   (*sel_outinitfunc)(t_topology *top, gmx_ana_selvalue_t *out,
+typedef void  (*sel_outinitfunc)(t_topology *top, gmx_ana_selvalue_t *out,
                                  void *data);
 /*! \brief
  * Frees the internal data.
@@ -509,7 +504,7 @@ typedef void  (*sel_freefunc)(void *data);
  * For static methods, it is called once, with \p fr and \p pbc set to
  * NULL.
  */
-typedef int   (*sel_framefunc)(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+typedef void  (*sel_framefunc)(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                                void *data);
 /*! \brief
  * Evaluates a selection method.
@@ -536,7 +531,7 @@ typedef int   (*sel_framefunc)(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  * without freeing; it is the responsibility of this function to provide
  * pointers that can be discarded without memory leaks.
  */
-typedef int   (*sel_updatefunc)(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+typedef void  (*sel_updatefunc)(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out,
                                 void *data);
 /*! \brief
@@ -564,7 +559,7 @@ typedef int   (*sel_updatefunc)(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  * without freeing; it is the responsibility of this function to provide
  * pointers that can be discarded without memory leaks.
  */
-typedef int   (*sel_updatefunc_pos)(t_topology *top, t_trxframe *fr, t_pbc *pbc,
+typedef void  (*sel_updatefunc_pos)(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                                     struct gmx_ana_pos_t *pos,
                                     gmx_ana_selvalue_t *out,
                                     void *data);
@@ -661,8 +656,4 @@ gmx_ana_selmethod_register_defaults(struct gmx_sel_symtab_t *symtab);
 gmx_ana_selparam_t *
 gmx_ana_selmethod_find_param(const char *name, gmx_ana_selmethod_t *method);
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif
index d5aeb5e6f0acebecef300b51fe4e604e4cd818eb..5503a2438b1bd63edeb4038b2172ff2369ff3d9a 100644 (file)
@@ -42,8 +42,8 @@
 #include <maths.h>
 #include <macros.h>
 #include <smalloc.h>
-#include <gmx_fatal.h>
 
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/selmethod.h"
 
 /** Defines the comparison operator for comparison expressions. */
@@ -101,13 +101,13 @@ typedef struct
 static void *
 init_data_compare(int npar, gmx_ana_selparam_t *param);
 /** Initializes data for comparison expression evaluation. */
-static int
+static void
 init_compare(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Frees the memory allocated for comparison expression evaluation. */
 static void
 free_data_compare(void *data);
 /** Evaluates comparison expressions. */
-static int
+static void
 evaluate_compare(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                  gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 
@@ -347,7 +347,7 @@ convert_int_real(int n, t_compare_value *val)
  *
  * The values are rounded such that the same comparison operator can be used.
  */
-static int
+static void
 convert_real_int(int n, t_compare_value *val, e_comparison_t cmpt, gmx_bool bRight)
 {
     int   i;
@@ -373,13 +373,15 @@ convert_real_int(int n, t_compare_value *val, e_comparison_t cmpt, gmx_bool bRig
                 break;
             case CMP_EQUAL:
             case CMP_NEQ:
-                fprintf(stderr, "comparing equality an integer expression and a real value\n");
                 sfree(iv);
-                return EINVAL;
+                /* TODO: Implement, although it isn't typically very useful.
+                 * Implementation is only a matter or proper initialization,
+                 * the evaluation function can already handle this case with
+                 * proper preparations. */
+                GMX_THROW(gmx::NotImplementedError("Equality comparison between dynamic integer and static real expressions not implemented"));
             case CMP_INVALID: /* Should not be reached */
-                gmx_bug("internal error");
                 sfree(iv);
-                return EINVAL;
+                GMX_THROW(gmx::InternalError("Invalid comparison type"));
         }
     }
     /* Free the previous value if one is present. */
@@ -387,7 +389,6 @@ convert_real_int(int n, t_compare_value *val, e_comparison_t cmpt, gmx_bool bRig
     val->i      = iv;
     val->flags &= ~CMP_REALVAL;
     val->flags |= CMP_ALLOCINT;
-    return 0;
 }
 
 /*!
@@ -397,7 +398,7 @@ convert_real_int(int n, t_compare_value *val, e_comparison_t cmpt, gmx_bool bRig
  * \param[in] data  Should point to a \c t_methoddata_compare.
  * \returns   0 if the input data is valid, -1 on error.
  */
-static int
+static void
 init_compare(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_compare *d = (t_methoddata_compare *)data;
@@ -408,15 +409,13 @@ init_compare(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     n2 = init_comparison_value(&d->right, &param[3]);
     if (n1 == 0 || n2 == 0)
     {
-        gmx_bug("one of the values for comparison missing");
-        return -1;
+        GMX_THROW(gmx::InternalError("One of the values for comparison missing"));
     }
     /* Store the comparison type */
     d->cmpt = comparison_type(d->cmpop);
     if (d->cmpt == CMP_INVALID)
     {
-        gmx_bug("invalid comparison type");
-        return -1;
+        GMX_THROW(gmx::InternalError("Invalid comparison type"));
     }
     /* Convert the values to the same type */
     if ((d->left.flags & CMP_REALVAL) && !(d->right.flags & CMP_REALVAL))
@@ -431,10 +430,7 @@ init_compare(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
         }
         else /* d->left is static */
         {
-            if (convert_real_int(n1, &d->left, d->cmpt, FALSE))
-            {
-                return -1;
-            }
+            convert_real_int(n1, &d->left, d->cmpt, FALSE);
         }
     }
     else if (!(d->left.flags & CMP_REALVAL) && (d->right.flags & CMP_REALVAL))
@@ -458,13 +454,9 @@ init_compare(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
         }
         else /* d->right is static */
         {
-            if (convert_real_int(n2, &d->right, d->cmpt, TRUE))
-            {
-                return -1;
-            }
+            convert_real_int(n2, &d->right, d->cmpt, TRUE);
         }
     }
-    return 0;
 }
 
 /*!
@@ -503,9 +495,8 @@ free_data_compare(void *data)
  * \param[in]  g     Evaluation index group.
  * \param[out] out   Output data structure (\p out->u.g is used).
  * \param[in]  data  Should point to a \c t_methoddata_compare.
- * \returns    0 for success.
  */
-static int
+static void
 evaluate_compare_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -543,7 +534,6 @@ evaluate_compare_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         }
     }
     out->u.g->isize = ig;
-    return 0;
 }
 
 /*!
@@ -553,9 +543,8 @@ evaluate_compare_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  * \param[in]  g     Evaluation index group.
  * \param[out] out   Output data structure (\p out->u.g is used).
  * \param[in]  data  Should point to a \c t_methoddata_compare.
- * \returns    0 for success.
  */
-static int
+static void
 evaluate_compare_real(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                       gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -593,7 +582,6 @@ evaluate_compare_real(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         }
     }
     out->u.g->isize = ig;
-    return 0;
 }
 
 /*!
@@ -603,9 +591,8 @@ evaluate_compare_real(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  * \param[in]  g     Evaluation index group.
  * \param[out] out   Output data structure (\p out->u.g is used).
  * \param[in]  data  Should point to a \c t_methoddata_compare.
- * \returns    0 for success.
  */
-static int
+static void
 evaluate_compare(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                  gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -613,11 +600,10 @@ evaluate_compare(t_topology *top, t_trxframe *fr, t_pbc *pbc,
 
     if (!((d->left.flags | d->right.flags) & CMP_REALVAL))
     {
-        return evaluate_compare_int(top, fr, pbc, g, out, data);
+        evaluate_compare_int(top, fr, pbc, g, out, data);
     }
     else
     {
-        return evaluate_compare_real(top, fr, pbc, g, out, data);
+        evaluate_compare_real(top, fr, pbc, g, out, data);
     }
-    return 0;
 }
index 1a6b4c18562f0d466d81d28864bc221c73e98da1..8c6da795f9bf21dc2347c414ee039f907a79c80c 100644 (file)
@@ -47,6 +47,7 @@
 #include <smalloc.h>
 #include <vec.h>
 
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/nbsearch.h"
 #include "gromacs/selection/position.h"
 #include "gromacs/selection/selmethod.h"
@@ -70,20 +71,20 @@ typedef struct
 static void *
 init_data_common(int npar, gmx_ana_selparam_t *param);
 /** Initializes a distance-based selection method. */
-static int
+static void
 init_common(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Frees the data allocated for a distance-based selection method. */
 static void
 free_data_common(void *data);
 /** Initializes the evaluation of a distance-based within selection method for a frame. */
-static int
+static void
 init_frame_common(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data);
 /** Evaluates the \p distance selection method. */
-static int
+static void
 evaluate_distance(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p within selection method. */
-static int
+static void
 evaluate_within(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
 
@@ -210,17 +211,16 @@ init_data_common(int npar, gmx_ana_selparam_t *param)
  * (\c t_methoddata_distance::nb).
  * Also checks that the cutoff is valid.
  */
-static int
+static void
 init_common(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_distance *d = (t_methoddata_distance *)data;
 
     if ((param[0].flags & SPAR_SET) && d->cutoff <= 0)
     {
-        fprintf(stderr, "error: distance cutoff should be > 0");
-        return -1;
+        GMX_THROW(gmx::InvalidInputError("Distance cutoff should be > 0"));
     }
-    return gmx_ana_nbsearch_create(&d->nb, d->cutoff, d->p.nr);
+    d->nb = gmx_ana_nbsearch_create(d->cutoff, d->p.nr);
 }
 
 /*!
@@ -249,12 +249,12 @@ free_data_common(void *data)
  *
  * Initializes the neighborhood search for the current frame.
  */
-static int
+static void
 init_frame_common(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
 {
     t_methoddata_distance *d = (t_methoddata_distance *)data;
 
-    return gmx_ana_nbsearch_pos_init(d->nb, pbc, &d->p);
+    gmx_ana_nbsearch_pos_init(d->nb, pbc, &d->p);
 }
 
 /*!
@@ -264,7 +264,7 @@ init_frame_common(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
  * Calculates the distance of each position from \c t_methoddata_distance::p
  * and puts them in \p out->u.r.
  */
-static int
+static void
 evaluate_distance(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
 {
@@ -281,7 +281,6 @@ evaluate_distance(t_topology *top, t_trxframe *fr, t_pbc *pbc,
             out->u.r[i] = n;
         }
     }
-    return 0;
 }
 
 /*!
@@ -291,7 +290,7 @@ evaluate_distance(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  * Finds the atoms that are closer than the defined cutoff to
  * \c t_methoddata_distance::xref and puts them in \p out.g.
  */
-static int
+static void
 evaluate_within(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
 {
@@ -306,5 +305,4 @@ evaluate_within(t_topology *top, t_trxframe *fr, t_pbc *pbc,
             gmx_ana_pos_append(NULL, out->u.g, pos, b, 0);
         }
     }
-    return 0;
 }
index 6f8d92453fc7cbbb3e745a46b39bc039c9cdd173..8321e77ad05951caf19b5caf2d3e1f525c30c91b 100644 (file)
 #include <smalloc.h>
 #include <vec.h>
 
+// FIXME: Should really be in the beginning, but causes compilation errors
+#include <algorithm>
+
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/indexutil.h"
 #include "gromacs/selection/position.h"
 #include "gromacs/selection/selection.h"
 
 #include "selelem.h"
 
+using std::min;
+using std::max;
+
 /*! \internal \brief
  * Internal data structure for the \p insolidangle selection method.
  *
@@ -211,7 +218,7 @@ typedef struct
 static void *
 init_data_insolidangle(int npar, gmx_ana_selparam_t *param);
 /** Initializes the \p insolidangle selection method. */
-static int
+static void
 init_insolidangle(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Sets the COM/COG data for the \p insolidangle selection method. */
 static void
@@ -220,13 +227,13 @@ set_comg_insolidangle(gmx_ana_pos_t *pos, void *data);
 static void
 free_data_insolidangle(void *data);
 /** Initializes the evaluation of the \p insolidangle selection method for a frame. */
-static int
+static void
 init_frame_insolidangle(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data);
 /** Internal helper function for evaluate_insolidangle(). */
 static gmx_bool
 accept_insolidangle(rvec x, t_pbc *pbc, void *data);
 /** Evaluates the \p insolidangle selection method. */
-static int
+static void
 evaluate_insolidangle(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                       gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
 
@@ -346,7 +353,7 @@ init_data_insolidangle(int npar, gmx_ana_selparam_t *param)
  * Converts t_methoddata_insolidangle::angcut to radians and allocates
  * and allocates memory for the bins used during the evaluation.
  */
-static int
+static void
 init_insolidangle(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_insolidangle *surf = (t_methoddata_insolidangle *)data;
@@ -354,8 +361,7 @@ init_insolidangle(t_topology *top, int npar, gmx_ana_selparam_t *param, void *da
 
     if (surf->angcut <= 0)
     {
-        fprintf(stderr, "error: angle cutoff should be > 0");
-        return -1;
+        GMX_THROW(gmx::InvalidInputError("Angle cutoff should be > 0"));
     }
 
     surf->angcut *= DEG2RAD;
@@ -376,8 +382,6 @@ init_insolidangle(t_topology *top, int npar, gmx_ana_selparam_t *param, void *da
     }
     surf->nbins = 0;
     snew(surf->bin, surf->maxbins);
-
-    return 0;
 }
 
 /*!
@@ -410,12 +414,11 @@ free_data_insolidangle(void *data)
  * \param[in]  fr   Current frame.
  * \param[in]  pbc  PBC structure.
  * \param      data Should point to a \ref t_methoddata_insolidangle.
- * \returns    0 on success, a non-zero error code on error.
  *
  * Creates a lookup structure that enables fast queries of whether a point
  * is within the solid angle or not.
  */
-static int
+static void
 init_frame_insolidangle(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
 {
     t_methoddata_insolidangle *d = (t_methoddata_insolidangle *)data;
@@ -439,7 +442,6 @@ init_frame_insolidangle(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
     }
     optimize_surface_points(d);
     d->cfrac = -1;
-    return 0;
 }
 
 /*!
@@ -474,7 +476,7 @@ accept_insolidangle(rvec x, t_pbc *pbc, void *data)
  * \c t_methoddata_insolidangle::span and centered at
  * \c t_methoddata_insolidangle::center, and stores the result in \p out->u.g.
  */
-static int
+static void
 evaluate_insolidangle(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                       gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
 {
@@ -489,7 +491,6 @@ evaluate_insolidangle(t_topology *top, t_trxframe *fr, t_pbc *pbc,
             gmx_ana_pos_append(NULL, out->u.g, pos, b, 0);
         }
     }
-    return 0;
 }
 
 /*!
@@ -852,7 +853,7 @@ store_surface_point(t_methoddata_insolidangle *surf, rvec x)
         tmax = acos(cos(theta) / cos(surf->angcut));
     }
     /* Find the first affected bin */
-    tbin = max(floor((theta - surf->angcut) / surf->tbinsize), 0);
+    tbin = max(floor((theta - surf->angcut) / surf->tbinsize), 0.0);
     theta1 = tbin * surf->tbinsize;
     if (theta1 < theta - surf->angcut)
     {
index c1b759de9ffe55443cd90d588a58e6b115c7a744..fd91e3eb762cd181155fa8960948d1baa0f34538 100644 (file)
@@ -72,27 +72,27 @@ init_data_kwreal(int npar, gmx_ana_selparam_t *param);
 static void *
 init_data_kwstr(int npar, gmx_ana_selparam_t *param);
 /** Initializes data for integer keyword evaluation. */
-static int
+static void
 init_kwint(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Initializes data for real keyword evaluation. */
-static int
+static void
 init_kwreal(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Initializes data for string keyword evaluation. */
-static int
+static void
 init_kwstr(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Frees the memory allocated for string keyword evaluation. */
 static void
 free_data_kwstr(void *data);
 /** Evaluates integer selection keywords. */
-static int
+static void
 evaluate_keyword_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates real selection keywords. */
-static int
+static void
 evaluate_keyword_real(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                       gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates string selection keywords. */
-static int
+static void
 evaluate_keyword_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 
@@ -225,19 +225,19 @@ gmx_ana_selmethod_t sm_keyword_str = {
 };
 
 /** Initializes keyword evaluation for an arbitrary group. */
-static int
+static void
 init_kweval(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Initializes output for keyword evaluation in an arbitrary group. */
-static int
+static void
 init_output_kweval(t_topology *top, gmx_ana_selvalue_t *out, void *data);
 /** Frees the data allocated for keyword evaluation in an arbitrary group. */
 static void
 free_data_kweval(void *data);
 /** Initializes frame evaluation for keyword evaluation in an arbitrary group. */
-static int
+static void
 init_frame_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data);
 /** Evaluates keywords in an arbitrary group. */
-static int
+static void
 evaluate_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 
@@ -285,9 +285,8 @@ init_data_kwint(int npar, gmx_ana_selparam_t *param)
  * \param[in] npar  Not used (should be 2).
  * \param[in] param Method parameters (should point to \ref smparams_keyword_int).
  * \param[in] data  Should point to \ref t_methoddata_kwint.
- * \returns   0 (the initialization always succeeds).
  */
-static int
+static void
 init_kwint(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_kwint *d = (t_methoddata_kwint *)data;
@@ -295,7 +294,6 @@ init_kwint(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     d->v = param[0].val.u.i;
     d->n = param[1].val.nr;
     d->r = param[1].val.u.i;
-    return 0;
 }
 
 /*!
@@ -306,7 +304,7 @@ init_kwint(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  * \c t_methoddata_kwint structure for this selection.
  * Matching atoms are stored in \p out->u.g.
  */
-static int
+static void
 evaluate_keyword_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -347,7 +345,6 @@ evaluate_keyword_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
             out->u.g->index[out->u.g->isize++] = g->index[i];
         }
     }
-    return 0;
 }
 
 
@@ -378,7 +375,7 @@ init_data_kwreal(int npar, gmx_ana_selparam_t *param)
  * \param[in] data  Should point to \ref t_methoddata_kwreal.
  * \returns   0 (the initialization always succeeds).
  */
-static int
+static void
 init_kwreal(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_kwreal *d = (t_methoddata_kwreal *)data;
@@ -386,7 +383,6 @@ init_kwreal(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     d->v = param[0].val.u.r;
     d->n = param[1].val.nr;
     d->r = param[1].val.u.r;
-    return 0;
 }
 
 /*!
@@ -397,7 +393,7 @@ init_kwreal(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  * \c t_methoddata_kwreal structure for this selection.
  * Matching atoms are stored in \p out->u.g.
  */
-static int
+static void
 evaluate_keyword_real(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -438,7 +434,6 @@ evaluate_keyword_real(t_topology *top, t_trxframe *fr, t_pbc *pbc,
             out->u.g->index[out->u.g->isize++] = g->index[i];
         }
     }
-    return 0;
 }
 
 
@@ -467,9 +462,8 @@ init_data_kwstr(int npar, gmx_ana_selparam_t *param)
  * \param[in] npar  Not used (should be 2).
  * \param[in] param Method parameters (should point to \ref smparams_keyword_str).
  * \param[in] data  Should point to \ref t_methoddata_kwstr.
- * \returns   0 (the initialization always succeeds).
  */
-static int
+static void
 init_kwstr(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_kwstr *d = (t_methoddata_kwstr *)data;
@@ -484,7 +478,7 @@ init_kwstr(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     /* Return if this is not the first time */
     if (d->m)
     {
-        return 0;
+        return;
     }
     snew(d->m, d->n);
     for (i = 0; i < d->n; ++i)
@@ -501,6 +495,7 @@ init_kwstr(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
         }
         if (bRegExp)
         {
+            // TODO: Get rid of these prints to stderr
 #ifdef USE_REGEX
             snew(buf, strlen(s) + 3);
             sprintf(buf, "^%s$", s);
@@ -523,7 +518,6 @@ init_kwstr(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
         }
         d->m[i].bRegExp = bRegExp;
     }
-    return 0;
 }
 
 /*!
@@ -560,7 +554,7 @@ free_data_kwstr(void *data)
  * Wildcards are allowed in the strings.
  * Matching atoms are stored in \p out->u.g.
  */
-static int
+static void
 evaluate_keyword_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -598,7 +592,6 @@ evaluate_keyword_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
             out->u.g->index[out->u.g->isize++] = g->index[i];
         }
     }
-    return 0;
 }
 
 
@@ -615,12 +608,12 @@ evaluate_keyword_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Calls the initialization method of the wrapped keyword.
  */
-static int
+static void
 init_kweval(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
 
-    return d->kwmethod->init(top, 0, NULL, d->kwmdata);
+    d->kwmethod->init(top, 0, NULL, d->kwmdata);
 }
 
 /*!
@@ -629,13 +622,12 @@ init_kweval(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  * \param[in,out] data  Should point to \c t_methoddata_kweval.
  * \returns       0 for success.
  */
-static int
+static void
 init_output_kweval(t_topology *top, gmx_ana_selvalue_t *out, void *data)
 {
     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
 
     out->nr = d->g.isize;
-    return 0;
 }
 
 /*!
@@ -661,12 +653,12 @@ free_data_kweval(void *data)
  * Creates a lookup structure that enables fast queries of whether a point
  * is within the solid angle or not.
  */
-static int
+static void
 init_frame_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
 {
     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
 
-    return d->kwmethod->init_frame(top, fr, pbc, d->kwmdata);
+    d->kwmethod->init_frame(top, fr, pbc, d->kwmdata);
 }
 
 /*!
@@ -677,13 +669,13 @@ init_frame_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
  * parameters, with the exception of using \c t_methoddata_kweval::g for the
  * evaluation group.
  */
-static int
+static void
 evaluate_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
 
-    return d->kwmethod->update(top, fr, pbc, &d->g, out, d->kwmdata);
+    d->kwmethod->update(top, fr, pbc, &d->g, out, d->kwmdata);
 }
 
 /*!
index b0a16e6b745bf1530c3b4361283b1a28a6a2cb47..95073d54111fe841fe93633cd9ffe767a856d159 100644 (file)
@@ -43,6 +43,7 @@
 #include <smalloc.h>
 #include <vec.h>
 
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/position.h"
 #include "gromacs/selection/selmethod.h"
 
@@ -65,23 +66,23 @@ typedef struct
 static void *
 init_data_merge(int npar, gmx_ana_selparam_t *param);
 /** Initializes data for the merging selection modifiers. */
-static int
+static void
 init_merge(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Initializes output for the \p merge selection modifier. */
-static int
+static void
 init_output_merge(t_topology *top, gmx_ana_selvalue_t *out, void *data);
 /** Initializes output for the \p plus selection modifier. */
-static int
+static void
 init_output_plus(t_topology *top, gmx_ana_selvalue_t *out, void *data);
 /** Frees the memory allocated for the merging selection modifiers. */
 static void
 free_data_merge(void *data);
 /** Evaluates the \p merge selection modifier. */
-static int
+static void
 evaluate_merge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                gmx_ana_pos_t *p, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p plus selection modifier. */
-static int
+static void
 evaluate_plus(t_topology *top, t_trxframe *fr, t_pbc *pbc,
               gmx_ana_pos_t *p, gmx_ana_selvalue_t *out, void *data);
 
@@ -179,7 +180,7 @@ init_data_merge(int npar, gmx_ana_selparam_t *param)
  * \param[in] data  Should point to a \p t_methoddata_merge.
  * \returns   0 if everything is successful, -1 on error.
  */
-static int
+static void
 init_merge(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_merge *d = (t_methoddata_merge *)data;
@@ -187,8 +188,7 @@ init_merge(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 
     if (d->stride < 0)
     {
-        fprintf(stderr, "error: stride for merging should be positive\n");
-        return -1;
+        GMX_THROW(gmx::InvalidInputError("Stride for merging should be positive"));
     }
     /* If no stride given, deduce it from the input sizes */
     if (d->stride == 0)
@@ -197,15 +197,13 @@ init_merge(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     }
     if (d->p1.nr != d->stride*d->p2.nr)
     {
-        fprintf(stderr, "error: the number of positions to be merged are not compatible\n");
-        return -1;
+        GMX_THROW(gmx::InconsistentInputError("The number of positions to be merged are not compatible"));
     }
     /* We access the m.b.nra field instead of g->isize in the position
      * data structures to handle cases where g is NULL
      * (this occurs with constant positions. */
     gmx_ana_index_reserve(&d->g, d->p1.m.b.nra + d->p2.m.b.nra);
     d->g.isize = d->p1.m.b.nra + d->p2.m.b.nra;
-    return 0;
 }
 
 /*! \brief
@@ -214,9 +212,8 @@ init_merge(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  * \param[in]     top   Topology data structure.
  * \param[in,out] out   Pointer to output data structure.
  * \param[in,out] data  Should point to \c t_methoddata_merge.
- * \returns       0 for success.
  */
-static int
+static void
 init_output_common(t_topology *top, gmx_ana_selvalue_t *out, void *data)
 {
     t_methoddata_merge *d = (t_methoddata_merge *)data;
@@ -242,16 +239,14 @@ init_output_common(t_topology *top, gmx_ana_selvalue_t *out, void *data)
     gmx_ana_pos_set_evalgrp(out->u.p, &d->g);
     gmx_ana_pos_empty_init(out->u.p);
     d->g.isize = 0;
-    return 0;
 }
 
 /*!
  * \param[in]     top   Topology data structure.
  * \param[in,out] out   Pointer to output data structure.
  * \param[in,out] data  Should point to \c t_methoddata_merge.
- * \returns       0 for success.
  */
-static int
+static void
 init_output_merge(t_topology *top, gmx_ana_selvalue_t *out, void *data)
 {
     t_methoddata_merge *d = (t_methoddata_merge *)data;
@@ -266,16 +261,14 @@ init_output_merge(t_topology *top, gmx_ana_selvalue_t *out, void *data)
         }
         gmx_ana_pos_append_init(out->u.p, &d->g, &d->p2, i);
     }
-    return 0;
 }
 
 /*!
  * \param[in]     top   Topology data structure.
  * \param[in,out] out   Pointer to output data structure.
  * \param[in,out] data  Should point to \c t_methoddata_merge.
- * \returns       0 for success.
  */
-static int
+static void
 init_output_plus(t_topology *top, gmx_ana_selvalue_t *out, void *data)
 {
     t_methoddata_merge *d = (t_methoddata_merge *)data;
@@ -290,7 +283,6 @@ init_output_plus(t_topology *top, gmx_ana_selvalue_t *out, void *data)
     {
         gmx_ana_pos_append_init(out->u.p, &d->g, &d->p2, i);
     }
-    return 0;
 }
 
 /*!
@@ -313,9 +305,8 @@ free_data_merge(void *data)
  * \param[in]  p     Positions to merge (should point to \p data->p1).
  * \param[out] out   Output data structure (\p out->u.p is used).
  * \param[in]  data  Should point to a \p t_methoddata_merge.
- * \returns    0 on success.
  */
-static int
+static void
 evaluate_merge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                gmx_ana_pos_t *p, gmx_ana_selvalue_t *out, void *data)
 {
@@ -325,8 +316,7 @@ evaluate_merge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
 
     if (d->p1.nr != d->stride*d->p2.nr)
     {
-        fprintf(stderr, "error: the number of positions to be merged are not compatible\n");
-        return -1;
+        GMX_THROW(gmx::InconsistentInputError("The number of positions to be merged are not compatible"));
     }
     d->g.isize = 0;
     gmx_ana_pos_empty(out->u.p);
@@ -345,7 +335,6 @@ evaluate_merge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         gmx_ana_pos_append(out->u.p, &d->g, &d->p2, i, refid);
     }
     gmx_ana_pos_append_finish(out->u.p);
-    return 0;
 }
 
 /*!
@@ -355,9 +344,8 @@ evaluate_merge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  * \param[in]  p     Positions to merge (should point to \p data->p1).
  * \param[out] out   Output data structure (\p out->u.p is used).
  * \param[in]  data  Should point to a \p t_methoddata_merge.
- * \returns    0 on success.
  */
-static int
+static void
 evaluate_plus(t_topology *top, t_trxframe *fr, t_pbc *pbc,
               gmx_ana_pos_t *p, gmx_ana_selvalue_t *out, void *data)
 {
@@ -382,5 +370,4 @@ evaluate_plus(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         gmx_ana_pos_append(out->u.p, &d->g, &d->p2, i, refid);
     }
     gmx_ana_pos_append_finish(out->u.p);
-    return 0;
 }
index 7b6deeb5672bd9182c2da41cee218edbb7669606..1367086d16262586f37c47c59d402fad42c4be2f 100644 (file)
 #include <smalloc.h>
 #include <vec.h>
 
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/position.h"
 #include "gromacs/selection/selmethod.h"
+#include "gromacs/utility/format.h"
 
 /*! \internal \brief
  * Data structure for the \p permute selection modifier.
@@ -67,16 +69,16 @@ typedef struct
 static void *
 init_data_permute(int npar, gmx_ana_selparam_t *param);
 /** Initializes data for the \p permute selection modifier. */
-static int
+static void
 init_permute(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Initializes output for the \p permute selection modifier. */
-static int
+static void
 init_output_permute(t_topology *top, gmx_ana_selvalue_t *out, void *data);
 /** Frees the memory allocated for the \p permute selection modifier. */
 static void
 free_data_permute(void *data);
 /** Evaluates the \p permute selection modifier. */
-static int
+static void
 evaluate_permute(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                  gmx_ana_pos_t *p, gmx_ana_selvalue_t *out, void *data);
 
@@ -145,7 +147,7 @@ init_data_permute(int npar, gmx_ana_selparam_t *param)
  * \param[in] data  Should point to a \p t_methoddata_permute.
  * \returns   0 if the input permutation is valid, -1 on error.
  */
-static int
+static void
 init_permute(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_permute *d = (t_methoddata_permute *)data;
@@ -156,9 +158,8 @@ init_permute(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     d->perm = param[1].val.u.i;
     if (d->p.nr % d->n != 0)
     {
-        fprintf(stderr, "error: the number of positions to be permuted is not divisible by %d\n",
-                d->n);
-        return -1;
+        GMX_THROW(gmx::InconsistentInputError(
+                    gmx::formatString("The number of positions to be permuted is not divisible by %d", d->n)));
     }
     snew(d->rperm, d->n);
     for (i = 0; i < d->n; ++i)
@@ -170,26 +171,22 @@ init_permute(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
         d->perm[i]--;
         if (d->perm[i] < 0 || d->perm[i] >= d->n)
         {
-            fprintf(stderr, "invalid permutation");
-            return -1;
+            GMX_THROW(gmx::InvalidInputError("Invalid permutation"));
         }
         if (d->rperm[d->perm[i]] >= 0)
         {
-            fprintf(stderr, "invalid permutation");
-            return -1;
+            GMX_THROW(gmx::InvalidInputError("Invalid permutation"));
         }
         d->rperm[d->perm[i]] = i;
     }
-    return 0;
 }
 
 /*!
  * \param[in]     top   Topology data structure.
  * \param[in,out] out   Pointer to output data structure.
  * \param[in,out] data  Should point to \c t_methoddata_permute.
- * \returns       0 for success.
  */
-static int
+static void
 init_output_permute(t_topology *top, gmx_ana_selvalue_t *out, void *data)
 {
     t_methoddata_permute *d = (t_methoddata_permute *)data;
@@ -207,7 +204,6 @@ init_output_permute(t_topology *top, gmx_ana_selvalue_t *out, void *data)
             gmx_ana_pos_append_init(out->u.p, &d->g, &d->p, b);
         }
     }
-    return 0;
 }
 
 /*!
@@ -236,7 +232,7 @@ free_data_permute(void *data)
  * Returns -1 if the size of \p p is not divisible by the number of
  * elements in the permutation.
  */
-static int
+static void
 evaluate_permute(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                  gmx_ana_pos_t *p, gmx_ana_selvalue_t *out, void *data)
 {
@@ -246,9 +242,8 @@ evaluate_permute(t_topology *top, t_trxframe *fr, t_pbc *pbc,
 
     if (d->p.nr % d->n != 0)
     {
-        fprintf(stderr, "error: the number of positions to be permuted is not divisible by %d\n",
-                d->n);
-        return -1;
+        GMX_THROW(gmx::InconsistentInputError(
+                    gmx::formatString("The number of positions to be permuted is not divisible by %d", d->n)));
     }
     d->g.isize = 0;
     gmx_ana_pos_empty(out->u.p);
@@ -267,5 +262,4 @@ evaluate_permute(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         }
     }
     gmx_ana_pos_append_finish(out->u.p);
-    return 0;
 }
index f75422761059cf521076f8b14f70acbc57381ead..dba49af332955644df70210556260624fcacb018 100644 (file)
@@ -77,22 +77,22 @@ init_data_pos(int npar, gmx_ana_selparam_t *param);
 static void
 set_poscoll_pos(gmx_ana_poscalc_coll_t *pcc, void *data);
 /** Initializes position evaluation keywords. */
-static int
+static void
 init_kwpos(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Initializes the \p cog selection method. */
-static int
+static void
 init_cog(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Initializes the \p cog selection method. */
-static int
+static void
 init_com(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Initializes output for position evaluation selection methods. */
-static int
+static void
 init_output_pos(t_topology *top, gmx_ana_selvalue_t *out, void *data);
 /** Frees the data allocated for position evaluation selection methods. */
 static void
 free_data_pos(void *data);
 /** Evaluates position evaluation selection methods. */
-static int
+static void
 evaluate_pos(t_topology *top, t_trxframe *fr, t_pbc *pbc,
              gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 
@@ -256,11 +256,10 @@ _gmx_selelem_set_kwpos_flags(t_selelem *sel, int flags)
  * The \c t_methoddata_pos::type field should have been initialized
  * externally using _gmx_selelem_set_kwpos_type().
  */
-static int
+static void
 init_kwpos(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_pos *d = (t_methoddata_pos *)data;
-    int               rc;
 
     if (!(param[0].flags & SPAR_DYNAMIC))
     {
@@ -270,12 +269,8 @@ init_kwpos(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     {
         d->flags |= POS_DYNAMIC;
     }
-    // FIXME: This may throw, but only on internal errors.
-    // Will be taken automatically care of when selection compilation fully
-    // uses exceptions.
     gmx_ana_poscalc_create_enum(&d->pc, d->pcc, d->type, d->flags);
     gmx_ana_poscalc_set_maxindex(d->pc, &d->g);
-    return 0;
 }
 
 /*!
@@ -285,17 +280,15 @@ init_kwpos(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  * \param[in,out] data  Should point to \c t_methoddata_pos.
  * \returns       0 on success, a non-zero error code on error.
  */
-static int
+static void
 init_cog(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_pos *d = (t_methoddata_pos *)data;
-    int               rc;
 
     d->flags = (param[0].flags & SPAR_DYNAMIC) ? POS_DYNAMIC : 0;
     gmx_ana_poscalc_create(&d->pc, d->pcc, d->bPBC ? POS_ALL_PBC : POS_ALL,
                            d->flags);
     gmx_ana_poscalc_set_maxindex(d->pc, &d->g);
-    return 0;
 }
 
 /*!
@@ -305,18 +298,16 @@ init_cog(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  * \param[in,out] data  Should point to \c t_methoddata_pos.
  * \returns       0 on success, a non-zero error code on error.
  */
-static int
+static void
 init_com(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_pos *d = (t_methoddata_pos *)data;
-    int               rc;
 
     d->flags  = (param[0].flags & SPAR_DYNAMIC) ? POS_DYNAMIC : 0;
     d->flags |= POS_MASS;
     gmx_ana_poscalc_create(&d->pc, d->pcc, d->bPBC ? POS_ALL_PBC : POS_ALL,
                            d->flags);
     gmx_ana_poscalc_set_maxindex(d->pc, &d->g);
-    return 0;
 }
 
 /*!
@@ -325,14 +316,13 @@ init_com(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  * \param[in,out] data  Should point to \c t_methoddata_pos.
  * \returns       0 for success.
  */
-static int
+static void
 init_output_pos(t_topology *top, gmx_ana_selvalue_t *out, void *data)
 {
     t_methoddata_pos *d = (t_methoddata_pos *)data;
 
     gmx_ana_poscalc_init_pos(d->pc, out->u.p);
     gmx_ana_pos_set_evalgrp(out->u.p, &d->g);
-    return 0;
 }
 
 /*!
@@ -357,12 +347,11 @@ free_data_pos(void *data)
  * Calculates the positions using \c t_methoddata_pos::pc for the index group
  * in \c t_methoddata_pos::g and stores the results in \p out->u.p.
  */
-static int
+static void
 evaluate_pos(t_topology *top, t_trxframe *fr, t_pbc *pbc,
              gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
     t_methoddata_pos *d = (t_methoddata_pos *)data;
 
     gmx_ana_poscalc_update(d->pc, out->u.p, &d->g, fr, pbc);
-    return 0;
 }
index 2108f701d0e02289f6411a6e8b1c9efad18f58de..d8a5c1e8548cdf323a6a6152e2b383b28be827eb 100644 (file)
@@ -45,6 +45,7 @@
 #include <smalloc.h>
 #include <string2.h>
 
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/selmethod.h"
 
 #include "keywords.h"
@@ -97,23 +98,23 @@ typedef struct
 static void *
 init_data_same(int npar, gmx_ana_selparam_t *param);
 /** Initializes the \p same selection method. */
-static int
+static void
 init_same(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Frees the data allocated for the \p same selection method. */
 static void
 free_data_same(void *data);
 /** Initializes the evaluation of the \p same selection method for a frame. */
-static int
+static void
 init_frame_same_int(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data);
 /** Evaluates the \p same selection method. */
-static int
+static void
 evaluate_same_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Initializes the evaluation of the \p same selection method for a frame. */
-static int
+static void
 init_frame_same_str(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data);
 /** Evaluates the \p same selection method. */
-static int
+static void
 evaluate_same_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                  gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 
@@ -263,7 +264,7 @@ _gmx_selelem_custom_init_same(gmx_ana_selmethod_t **method,
  * \param   data  Pointer to \ref t_methoddata_same to initialize.
  * \returns 0 on success, -1 on failure.
  */
-static int
+static void
 init_same(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     t_methoddata_same *d = (t_methoddata_same *)data;
@@ -276,11 +277,10 @@ init_same(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     }
     if (!(param[0].flags & SPAR_ATOMVAL))
     {
-        fprintf(stderr, "ERROR: the same selection keyword combined with a "
-                        "non-keyword does not make sense\n");
-        return -1;
+        GMX_THROW(gmx::InvalidInputError(
+                    "The 'same' selection keyword combined with a "
+                    "non-keyword does not make sense"));
     }
-    return 0;
 }
 
 /*!
@@ -316,12 +316,11 @@ cmp_int(const void *a, const void *b)
  * \param[in]  fr   Current frame.
  * \param[in]  pbc  PBC structure.
  * \param      data Should point to a \ref t_methoddata_same.
- * \returns    0 on success, a non-zero error code on error.
  *
  * Sorts the \c data->as.i array and removes identical values for faster and
  * simpler lookup.
  */
-static int
+static void
 init_frame_same_int(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
 {
     t_methoddata_same *d = (t_methoddata_same *)data;
@@ -357,7 +356,6 @@ init_frame_same_int(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
         }
         d->nas = j + 1;
     }
-    return 0;
 }
 
 /*!
@@ -370,7 +368,7 @@ init_frame_same_int(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
  * binary search of \c data->as is performed for each block of values in
  * \c data->val.
  */
-static int
+static void
 evaluate_same_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -429,7 +427,6 @@ evaluate_same_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
             d->bSorted = FALSE;
         }
     }
-    return 0;
 }
 
 /*! \brief
@@ -446,12 +443,11 @@ cmp_str(const void *a, const void *b)
  * \param[in]  fr   Current frame.
  * \param[in]  pbc  PBC structure.
  * \param      data Should point to a \ref t_methoddata_same.
- * \returns    0 on success, a non-zero error code on error.
  *
  * Sorts the \c data->as.s array and removes identical values for faster and
  * simpler lookup.
  */
-static int
+static void
 init_frame_same_str(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
 {
     t_methoddata_same *d = (t_methoddata_same *)data;
@@ -483,7 +479,6 @@ init_frame_same_str(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
         }
     }
     d->nas = j + 1;
-    return 0;
 }
 
 /*!
@@ -495,7 +490,7 @@ init_frame_same_str(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
  * A binary search of \c data->as is performed for each block of values in
  * \c data->val.
  */
-static int
+static void
 evaluate_same_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -529,5 +524,4 @@ evaluate_same_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
             }
         }
     }
-    return 0;
 }
index 79dcec1bba5956c77b2457467167a1072f16f628..ecf45ffd3af65337fd8f0348046be3cecfcc9c81 100644 (file)
 #include <config.h>
 #endif
 
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/selection/position.h"
 #include "gromacs/selection/selmethod.h"
 
 /** Evaluates the \p all selection keyword. */
-static int
+static void
 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
              gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p none selection keyword. */
-static int
+static void
 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
               gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p atomnr selection keyword. */
-static int
+static void
 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p resnr selection keyword. */
-static int
+static void
 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p resindex selection keyword. */
-static int
+static void
 evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Checks whether molecule information is present in the topology. */
-static int
+static void
 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Evaluates the \p molindex selection keyword. */
-static int
+static void
 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p name selection keyword. */
-static int
+static void
 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Checks whether atom types are present in the topology. */
-static int
+static void
 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Evaluates the \p type selection keyword. */
-static int
+static void
 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p insertcode selection keyword. */
-static int
+static void
 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                     gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p chain selection keyword. */
-static int
+static void
 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p mass selection keyword. */
-static int
+static void
 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
               gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p charge selection keyword. */
-static int
+static void
 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Checks whether PDB info is present in the topology. */
-static int
+static void
 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
 /** Evaluates the \p altloc selection keyword. */
-static int
+static void
 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p occupancy selection keyword. */
-static int
+static void
 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                    gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p betafactor selection keyword. */
-static int
+static void
 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                     gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p resname selection keyword. */
-static int
+static void
 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                  gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
 
 /** Evaluates the \p x selection keyword. */
-static int
+static void
 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
            gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p y selection keyword. */
-static int
+static void
 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
            gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
 /** Evaluates the \p z selection keyword. */
-static int
+static void
 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
            gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
 
@@ -401,12 +402,11 @@ gmx_ana_selmethod_t sm_z = {
  *
  * Copies \p g to \p out->u.g.
  */
-static int
+static void
 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
              gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
     gmx_ana_index_copy(out->u.g, g, FALSE);
-    return 0;
 }
 
 /*!
@@ -415,12 +415,11 @@ evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns an empty \p out->u.g.
  */
-static int
+static void
 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
               gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
     out->u.g->isize = 0;
-    return 0;
 }
 
 /*!
@@ -429,7 +428,7 @@ evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the indices for each atom in \p out->u.i.
  */
-static int
+static void
 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -440,7 +439,6 @@ evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.i[i] = g->index[i] + 1;
     }
-    return 0;
 }
 
 /*!
@@ -449,7 +447,7 @@ evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the residue numbers for each atom in \p out->u.i.
  */
-static int
+static void
 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -462,7 +460,6 @@ evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         resind = top->atoms.atom[g->index[i]].resind;
         out->u.i[i] = top->atoms.resinfo[resind].nr;
     }
-    return 0;
 }
 
 /*!
@@ -471,7 +468,7 @@ evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the residue indices for each atom in \p out->u.i.
  */
-static int
+static void
 evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -482,7 +479,6 @@ evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.i[i] = top->atoms.atom[g->index[i]].resind + 1;
     }
-    return 0;
 }
 
 /*!
@@ -494,7 +490,7 @@ evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * If molecule information is not found, also prints an error message.
  */
-static int
+static void
 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     gmx_bool bOk;
@@ -502,10 +498,8 @@ check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data
     bOk = (top != NULL && top->mols.nr > 0);
     if (!bOk)
     {
-        fprintf(stderr, "Molecule information not available in topology!\n");
-        return -1;
+        GMX_THROW(gmx::InconsistentInputError("Molecule information not available in topology"));
     }
-    return 0;
 }
 
 /*!
@@ -514,7 +508,7 @@ check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data
  *
  * Returns the molecule indices for each atom in \p out->u.i.
  */
-static int
+static void
 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -526,7 +520,6 @@ evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         while (top->mols.index[j + 1] <= g->index[i]) ++j;
         out->u.i[i] = j + 1;
     }
-    return 0;
 }
 
 /*!
@@ -535,7 +528,7 @@ evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the atom name for each atom in \p out->u.s.
  */
-static int
+static void
 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -546,7 +539,6 @@ evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.s[i] = *top->atoms.atomname[g->index[i]];
     }
-    return 0;
 }
 
 /*!
@@ -558,7 +550,7 @@ evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * If the atom types are not found, also prints an error message.
  */
-static int
+static void
 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     gmx_bool bOk;
@@ -566,10 +558,8 @@ check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     bOk = (top != NULL && top->atoms.atomtype != NULL);
     if (!bOk)
     {
-        fprintf(stderr, "Atom types not available in topology!\n");
-        return -1;
+        GMX_THROW(gmx::InconsistentInputError("Atom types not available in topology"));
     }
-    return 0;
 }
 
 /*!
@@ -579,7 +569,7 @@ check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  * Returns the atom type for each atom in \p out->u.s.
  * Segfaults if atom types are not found in the topology.
  */
-static int
+static void
 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                   gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -590,7 +580,6 @@ evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.s[i] = *top->atoms.atomtype[g->index[i]];
     }
-    return 0;
 }
 
 /*!
@@ -599,7 +588,7 @@ evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the residue name for each atom in \p out->u.s.
  */
-static int
+static void
 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                  gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -612,7 +601,6 @@ evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         resind = top->atoms.atom[g->index[i]].resind;
         out->u.s[i] = *top->atoms.resinfo[resind].name;
     }
-    return 0;
 }
 
 /*!
@@ -621,7 +609,7 @@ evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the insertion code for each atom in \p out->u.s.
  */
-static int
+static void
 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                     gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -634,7 +622,6 @@ evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         resind = top->atoms.atom[g->index[i]].resind;
         out->u.s[i][0] = top->atoms.resinfo[resind].ic;
     }
-    return 0;
 }
 
 /*!
@@ -643,7 +630,7 @@ evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the chain for each atom in \p out->u.s.
  */
-static int
+static void
 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -656,7 +643,6 @@ evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
         resind = top->atoms.atom[g->index[i]].resind;
         out->u.s[i][0] = top->atoms.resinfo[resind].chainid;
     }
-    return 0;
 }
 
 /*!
@@ -665,7 +651,7 @@ evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the mass for each atom in \p out->u.r.
  */
-static int
+static void
 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
               gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -676,7 +662,6 @@ evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.r[i] = top->atoms.atom[g->index[i]].m;
     }
-    return 0;
 }
 
 /*!
@@ -685,7 +670,7 @@ evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the charge for each atom in \p out->u.r.
  */
-static int
+static void
 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -696,7 +681,6 @@ evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.r[i] = top->atoms.atom[g->index[i]].q;
     }
-    return 0;
 }
 
 /*!
@@ -708,7 +692,7 @@ evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * If PDB info is not found, also prints an error message.
  */
-static int
+static void
 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
 {
     gmx_bool bOk;
@@ -716,10 +700,8 @@ check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
     bOk = (top != NULL && top->atoms.pdbinfo != NULL);
     if (!bOk)
     {
-        fprintf(stderr, "PDB info not available in topology!\n");
-        return -1;
+        GMX_THROW(gmx::InconsistentInputError("PDB info not available in topology"));
     }
-    return 0;
 }
 
 /*!
@@ -728,7 +710,7 @@ check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
  *
  * Returns the alternate location identifier for each atom in \p out->u.s.
  */
-static int
+static void
 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -739,7 +721,6 @@ evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.s[i][0] = top->atoms.pdbinfo[g->index[i]].altloc;
     }
-    return 0;
 }
 
 /*!
@@ -749,7 +730,7 @@ evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  * Returns the occupancy numbers for each atom in \p out->u.r.
  * Segfaults if PDB info is not found in the topology.
  */
-static int
+static void
 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                    gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -760,7 +741,6 @@ evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.r[i] = top->atoms.pdbinfo[g->index[i]].occup;
     }
-    return 0;
 }
 
 /*!
@@ -770,7 +750,7 @@ evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  * Returns the B-factors for each atom in \p out->u.r.
  * Segfaults if PDB info is not found in the topology.
  */
-static int
+static void
 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
                     gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
 {
@@ -781,7 +761,6 @@ evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
     {
         out->u.r[i] = top->atoms.pdbinfo[g->index[i]].bfac;
     }
-    return 0;
 }
 
 /*! \brief
@@ -830,13 +809,12 @@ evaluate_coord(t_trxframe *fr, gmx_ana_index_t *g, real out[],
  *
  * Returns the \p x coordinate for each atom in \p out->u.r.
  */
-static int
+static void
 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
            gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
 {
     out->nr = pos->g->isize;
     evaluate_coord(fr, pos->g, out->u.r, pos, XX);
-    return 0;
 }
 
 /*!
@@ -845,13 +823,12 @@ evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the \p y coordinate for each atom in \p out->u.r.
  */
-static int
+static void
 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
            gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
 {
     out->nr = pos->g->isize;
     evaluate_coord(fr, pos->g, out->u.r, pos, YY);
-    return 0;
 }
 
 /*!
@@ -860,11 +837,10 @@ evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
  *
  * Returns the \p z coordinate for each atom in \p out->u.r.
  */
-static int
+static void
 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
            gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
 {
     out->nr = pos->g->isize;
     evaluate_coord(fr, pos->g, out->u.r, pos, ZZ);
-    return 0;
 }
index 70ed345cda5f41400b353521e87826214bc1a7b4..2b0c0765bda2d8476005bfdb13b1645e8a2d2be6 100644 (file)
@@ -200,7 +200,7 @@ SelectionCollectionDataTest::runParser(const char *const *selections)
 void
 SelectionCollectionDataTest::runCompiler()
 {
-    ASSERT_EQ(0, _sc.compile());
+    ASSERT_NO_THROW(_sc.compile());
     ASSERT_EQ(_count, _sel.size());
     checkCompiled();
 }
@@ -241,7 +241,7 @@ void
 SelectionCollectionDataTest::runEvaluate()
 {
     ++_framenr;
-    ASSERT_EQ(0, _sc.evaluate(_frame, NULL));
+    ASSERT_NO_THROW(_sc.evaluate(_frame, NULL));
     for (size_t i = 0; i < _count; ++i)
     {
         SCOPED_TRACE(std::string("Checking selection \"") +
@@ -318,9 +318,11 @@ SelectionCollectionDataTest::runTest(const char *filename, const char * const *s
 TEST_F(SelectionCollectionTest, HandlesNoSelections)
 {
     EXPECT_FALSE(_sc.requiresTopology());
-    EXPECT_EQ(0, _sc.compile());
+    EXPECT_NO_THROW(_sc.compile());
 }
 
+// TODO: Tests for error conditions
+
 
 /********************************************************************
  * Tests for selection keywords
index 3c401f988a20a7aef25f18c4716ef57f1b22badb..bd0aa4746e11258cc76c4d9d74543518ae79760f 100644 (file)
@@ -223,12 +223,7 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
     }
 
     common.initTopology(&selections);
-    rc = selections.compile();
-    if (rc != 0)
-    {
-        // Error message has already been printed.
-        return 1;
-    }
+    selections.compile();
 
     const TopologyInformation &topology = common.topologyInformation();
     module->initAnalysis(topology);
@@ -252,12 +247,7 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
             set_pbc(ppbc, topology.ePBC(), frame.box);
         }
 
-        rc = selections.evaluate(&frame, ppbc);
-        if (rc != 0)
-        {
-            // Error message has already been printed.
-            return 1;
-        }
+        selections.evaluate(&frame, ppbc);
         module->analyzeFrame(nframes, frame, ppbc, pdata.get());
 
         nframes++;
index c1d42c1d8af432120f4ae56f3665001665bdc8b0..5d0a90803309c3c4409c1a4a73ef1076daedfba6 100644 (file)
@@ -52,29 +52,20 @@ namespace gmx
 class NeighborhoodSearch
 {
     public:
-        ~NeighborhoodSearch() { gmx_ana_nbsearch_free(_d); }
-
-        static int create(NeighborhoodSearch **nbp, real cutoff, int maxn)
+        NeighborhoodSearch(real cutoff, int maxn)
+            : _d(gmx_ana_nbsearch_create(cutoff, maxn))
         {
-            gmx_ana_nbsearch_t *d;
-            int rc = gmx_ana_nbsearch_create(&d, cutoff, maxn);
-            if (rc != 0)
-            {
-                *nbp = NULL;
-                return rc;
-            }
-            *nbp = new NeighborhoodSearch(d);
-            return 0;
         }
+        ~NeighborhoodSearch() { gmx_ana_nbsearch_free(_d); }
 
-        int init(t_pbc *pbc, int n, const rvec x[])
-        { return gmx_ana_nbsearch_init(_d, pbc, n, x); }
+        void init(t_pbc *pbc, int n, const rvec x[])
+        { gmx_ana_nbsearch_init(_d, pbc, n, x); }
 
-        int init(t_pbc *pbc, const gmx_ana_pos_t *p)
-        { return gmx_ana_nbsearch_pos_init(_d, pbc, p); }
+        void init(t_pbc *pbc, const gmx_ana_pos_t *p)
+        { gmx_ana_nbsearch_pos_init(_d, pbc, p); }
 
-        int setExclusions(int nexcl, atom_id *excl)
-        { return gmx_ana_nbsearch_set_excl(_d, nexcl, excl); }
+        void setExclusions(int nexcl, atom_id *excl)
+        { gmx_ana_nbsearch_set_excl(_d, nexcl, excl); }
 
 
         bool isWithin(const rvec x)
@@ -99,8 +90,6 @@ class NeighborhoodSearch
         { return gmx_ana_nbsearch_next_within(_d, jp); }
 
     private:
-        NeighborhoodSearch(gmx_ana_nbsearch_t *d) : _d(d) {}
-
         gmx_ana_nbsearch_t  *_d;
 };