Parcourir la source

New template methods

Eric Ramat il y a 7 ans
Parent
commit
a5ff0299b3

+ 37 - 156
src/artis/kernel/AbstractAtomicModel.hpp

@@ -31,6 +31,8 @@
 #include <artis/utils/DateTime.hpp>
 #include <artis/utils/Exception.hpp>
 
+#include <sstream>
+
 namespace artis { namespace kernel {
 
 template < typename T, typename U, typename V >
@@ -48,6 +50,9 @@ public:
     virtual ~AbstractAtomicModel()
     { }
 
+    virtual const Node < U >* atomic(unsigned int /* index */) const
+    { return this; }
+
     virtual void after(typename U::type t)
     {
 
@@ -81,35 +86,58 @@ public:
 
     virtual void compute(typename U::type t, bool update) = 0;
 
-    virtual double get(typename U::type t, unsigned int index) const
+    virtual const Any& get(typename U::type t, unsigned int index) const
     {
         if (type::last_time != t) {
             throw utils::InvalidGet("Variable not computed");
         }
-        return static_cast < const T* >(this)->*(
-            Internals < T, U >::get(index));
+        return Internals < T, U >::get(index);
     }
 
-    virtual int getI(typename U::type t, unsigned int index) const
+    template < typename W >
+    W get(typename U::type t, unsigned int index) const
     {
         if (type::last_time != t) {
             throw utils::InvalidGet("Variable not computed");
         }
-        return static_cast < const T* >(this)->*(
-            Internals < T, U >::getI(index));
+        Any value = Internals < T, U >::get(index);
+
+        return static_cast < const T* >(this)->*(value.get < T, W >());
     }
 
-    virtual bool getB(typename U::type t, unsigned int index) const
+    virtual std::string get(const ValueType& value_type, typename U::type t,
+                            unsigned int index) const
     {
         if (type::last_time != t) {
             throw utils::InvalidGet("Variable not computed");
         }
-        return static_cast < const T* >(this)->*(
-            Internals < T, U >::getB(index));
+        Any value = Internals < T, U >::get(index);
+
+        switch (value_type) {
+        case DOUBLE:
+            {
+                std::ostringstream ss;
+
+                ss << std::setprecision(10)
+                   << static_cast < const T* >(this)->*(
+                       value.get < T, double >());
+                return ss.str();
+            }
+        case INT:
+            return std::to_string(
+                static_cast < const T* >(this)->*(value.get < T, int >()));
+        case BOOL:
+            return std::to_string(
+                static_cast < const T* >(this)->*(value.get < T, bool >()));
+        default: return "NA";
+        }
     }
 
     virtual void init(typename U::type t, const V& parameters) = 0;
 
+    virtual bool is_atomic() const
+    { return true; }
+
     bool is_computed(typename U::type t, unsigned int /* index */) const
     { return type::last_time == t; }
 
@@ -137,153 +165,6 @@ public:
     { Externals < T, U >::updated = false; }
 };
 
-template < typename T, typename U, typename V >
-struct SA_t
-{
-    SA_t(double t, AbstractAtomicModel < T, U, V >* model,
-         unsigned int index) : t(t), model(model), index(index)
-    { }
-
-    double t;
-    AbstractAtomicModel < T, U, V >* model;
-    unsigned int index;
-};
-
-template < typename T, typename U, typename V >
-struct IN_SA_t : public SA_t < T, U, V >
-{
-    IN_SA_t(double t, AbstractAtomicModel < T, U, V >* model,
-            unsigned int index) : SA_t < T, U , V >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V >
-struct IN_SA_I_t : public IN_SA_t < T, U, V >
-{
-    IN_SA_I_t(double t, AbstractAtomicModel < T, U, V >* model,
-              unsigned int index) : IN_SA_t < T, U , V >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V >
-struct IN_SA_B_t : public IN_SA_t < T, U, V >
-{
-    IN_SA_B_t(double t, AbstractAtomicModel < T, U, V >* model,
-              unsigned int index) : IN_SA_t < T, U , V >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V >
-struct OUT_SA_t : public SA_t < T, U, V >
-{
-    OUT_SA_t(double t, AbstractAtomicModel < T, U, V >* model,
-            unsigned int index) : SA_t < T, U , V >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V >
-struct OUT_SA_I_t : public OUT_SA_t < T, U, V >
-{
-    OUT_SA_I_t(double t, AbstractAtomicModel < T, U, V >* model,
-               unsigned int index) : OUT_SA_t < T, U , V >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V >
-struct OUT_SA_B_t : public OUT_SA_t < T, U, V >
-{
-    OUT_SA_B_t(double t, AbstractAtomicModel < T, U, V >* model,
-               unsigned int index) : OUT_SA_t < T, U , V >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V >
-IN_SA_t < T, U, V > IN(double t, AbstractAtomicModel < T, U, V >* model,
-                       unsigned int index)
-{ return IN_SA_t < T, U, V >(t, model, index); }
-
-template < typename T, typename U, typename V >
-IN_SA_I_t < T, U, V > IN_I(double t, AbstractAtomicModel < T, U, V >* model,
-                           unsigned int index)
-{ return IN_SA_I_t < T, U, V >(t, model, index); }
-
-template < typename T, typename U, typename V >
-IN_SA_B_t < T, U, V > IN_B(double t, AbstractAtomicModel < T, U, V >* model,
-                           unsigned int index)
-{ return IN_SA_B_t < T, U, V >(t, model, index); }
-
-template < typename T, typename U, typename V >
-OUT_SA_t < T, U, V > OUT(double t,
-                         AbstractAtomicModel < T, U, V >* model,
-                         unsigned int index)
-{ return OUT_SA_t < T, U, V >(t, model, index); }
-
-template < typename T, typename U, typename V >
-OUT_SA_I_t < T, U, V > OUT_I(double t,
-                             AbstractAtomicModel < T, U, V >* model,
-                             unsigned int index)
-{ return OUT_SA_I_t < T, U, V >(t, model, index); }
-
-template < typename T, typename U, typename V >
-OUT_SA_B_t < T, U, V > OUT_B(double t,
-                             AbstractAtomicModel < T, U, V >* model,
-                             unsigned int index)
-{ return OUT_SA_B_t < T, U, V >(t, model, index); }
-
-template < typename T1, typename U1, typename V1,
-           typename T2, typename U2, typename V2 >
-void operator>>(OUT_SA_t < T2, U2, V2 > out, IN_SA_t < T1, U1, V1 > in)
-{
-    if (out.model->is_computed(out.t, out.index)) {
-        in.model->put(out.t, in.index, out.model->get(out.t, out.index));
-    }
-}
-
-template < typename T1, typename U1, typename V1,
-           typename T2, typename U2, typename V2 >
-void operator>>(OUT_SA_I_t < T2, U2, V2 > out, IN_SA_I_t < T1, U1, V1 > in)
-{
-    if (out.model->is_computed(out.t, out.index)) {
-        in.model->put(out.t, in.index, out.model->getI(out.t, out.index));
-    }
-}
-
-template < typename T1, typename U1, typename V1,
-           typename T2, typename U2, typename V2 >
-void operator>>(OUT_SA_B_t < T2, U2, V2 > out, IN_SA_B_t < T1, U1, V1 > in)
-{
-    if (out.model->is_computed(out.t, out.index)) {
-        in.model->put(out.t, in.index, out.model->getB(out.t, out.index));
-    }
-}
-
-template < typename T1, typename U1, typename V1, typename W1,
-           typename T2, typename U2, typename V2 >
-void operator>>(OUT_SA_t < T2, U2, V2 > out, IN_SC_t < T1, U1, V1, W1 > in)
-{
-    if (out.model->is_computed(out.t, out.index)) {
-        in.model->put(out.t, in.index, out.model->get(out.t, out.index));
-    }
-}
-
-template < typename T1, typename U1, typename V1, typename W1,
-           typename T2, typename U2, typename V2 >
-void operator>>(OUT_SA_B_t < T2, U2, V2 > out, IN_SC_B_t < T1, U1, V1, W1 > in)
-{
-    if (out.model->is_computed(out.t, out.index)) {
-        in.model->put(out.t, in.index, out.model->getB(out.t, out.index));
-    }
-}
-
-template < typename T1, typename U1, typename V1, typename W1,
-           typename T2, typename U2, typename V2 >
-void operator>>(OUT_SA_I_t < T2, U2, V2 > out, IN_SC_I_t < T1, U1, V1, W1 > in)
-{
-    if (out.model->is_computed(out.t, out.index)) {
-        in.model->put(out.t, in.index, out.model->getI(out.t, out.index));
-    }
-}
-
 } }
 
 #endif

+ 62 - 203
src/artis/kernel/AbstractCoupledModel.hpp

@@ -77,6 +77,18 @@ public:
 
     }
 
+    virtual const Node < U >* atomic(unsigned int index) const
+    {
+        typename AbstractCoupledModel::SubModelInternals::const_iterator it =
+            submodel_internals.find(index);
+
+        if (it == submodel_internals.end()) {
+            return this;
+        } else {
+            return it->second.first->atomic(it->second.second);
+        }
+    }
+
     virtual void before(typename U::type t)
     {
 
@@ -103,47 +115,75 @@ public:
 
     virtual void compute(typename U::type t, bool update) = 0;
 
-    virtual double get(typename U::type t, unsigned int index) const
+    virtual const Any& get(typename U::type t, unsigned int index) const
     {
         typename AbstractCoupledModel::SubModelInternals::const_iterator it =
             submodel_internals.find(index);
 
         if (it == submodel_internals.end()) {
-            return static_cast < const T* >(this)->*(
-                Internals < T, U >::get(index));
+            if (type::last_time != t) {
+                throw utils::InvalidGet("Variable not computed");
+            }
+            return Internals < T, U >::get(index);
         } else {
             return it->second.first->get(t, it->second.second);
         }
     }
 
-    virtual int getI(typename U::type t, unsigned int index) const
+    template < typename Z, typename K >
+    Z get(typename U::type t, unsigned int index) const
     {
         typename AbstractCoupledModel::SubModelInternals::const_iterator it =
             submodel_internals.find(index);
 
         if (it == submodel_internals.end()) {
-            return static_cast < const T* >(this)->*(
-                Internals < T, U >::getI(index));
+            if (type::last_time != t) {
+                throw utils::InvalidGet("Variable not computed");
+            }
+            const Any& value = Internals < T, U >::get(index);
+
+            return static_cast < const T* >(this)->*(value.get < T, Z >());
         } else {
-            return it->second.first->getI(t, it->second.second);
+            const Any& value = it->second.first->get(t, it->second.second);
+            const Node < U >* object = it->second.first->atomic(
+                it->second.second);
+
+            return static_cast < const K* >(object)->*(value.get < K, Z >());
         }
     }
 
-    virtual bool getB(typename U::type t, unsigned int index) const
+    virtual std::string get(const ValueType& value_type, typename U::type t,
+                            unsigned int index) const
     {
         typename AbstractCoupledModel::SubModelInternals::const_iterator it =
             submodel_internals.find(index);
 
         if (it == submodel_internals.end()) {
-            return static_cast < const T* >(this)->*(
-                Internals < T, U >::getB(index));
+            Any value = Internals < T, U >::get(index);
+
+            switch (value_type) {
+            case DOUBLE:
+                return std::to_string(
+                    static_cast < const T* >(this)->*(value.get < T,
+                                                      double >()));
+            case INT:
+                return std::to_string(
+                    static_cast < const T* >(this)->*(value.get < T, int >()));
+            case BOOL:
+                return std::to_string(
+                    static_cast < const T* >(this)->*(value.get < T, bool >()));
+            default: return "NA";
+            }
         } else {
-            return it->second.first->getB(t, it->second.second);
+            return it->second.first->get(value_type, t, it->second.second);
         }
     }
 
     virtual void init(typename U::type t, const V& parameters) = 0;
 
+    virtual bool is_atomic() const
+    { return false; }
+
     bool is_computed(typename U::type t, unsigned int index) const
     {
         typename AbstractCoupledModel::SubModelInternals::const_iterator it =
@@ -289,24 +329,17 @@ protected:
     void internal(unsigned int index, double T::* var)
     { Internals < T, U >::internal(index, var); }
 
-    void I(std::initializer_list < std::pair < unsigned int,
-           bool T::* > > internals)
-    { Internals < T, U >::I(internals); }
-
-    void I(std::initializer_list < std::pair < unsigned int,
-           int T::* > > internals)
-    { Internals < T, U >::I(internals); }
-
-    void I(std::initializer_list < std::pair < unsigned int,
-           double T::* > > internals)
-    { Internals < T, U >::I(internals); }
-
     void internal(unsigned int index, type* model, int sub_index)
     {
         submodel_internals[index] =
             std::pair < type*, int >(model, sub_index);
     }
 
+    template < typename Z >
+    void I(std::initializer_list < std::pair < unsigned int,
+           Z T::* > > list)
+    { Internals < T, U >::I(list); }
+
     void I(std::initializer_list < Var > internals)
     {
         for (typename std::initializer_list < Var >::iterator it =
@@ -318,8 +351,12 @@ protected:
 
     void submodel(unsigned int index, type* model)
     {
-        submodels[index] = model;
-        model->set_parent(this);
+        if (model) {
+            submodels[index] = model;
+            model->set_parent(this);
+        } else {
+            submodels[index] = 0;
+        }
     }
 
     void S(std::initializer_list < std::pair <  unsigned int,
@@ -348,184 +385,6 @@ private:
     Setsubmodels setsubmodels;
 };
 
-template < typename T, typename U, typename V, typename W >
-struct SC_t
-{
-    SC_t(double t, AbstractCoupledModel < T, U, V, W >* model,
-         unsigned int index) : t(t), model(model), index(index)
-    { }
-
-    double t;
-    AbstractCoupledModel < T, U, V, W >* model;
-    unsigned int index;
-};
-
-template < typename T, typename U, typename V, typename W >
-struct IN_SC_t : public SC_t < T, U, V , W >
-{
-    IN_SC_t(double t, AbstractCoupledModel < T, U, V, W >* model,
-             unsigned int index) : SC_t < T, U, V, W >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V, typename W >
-struct IN_SC_I_t : public IN_SC_t < T, U, V , W >
-{
-    IN_SC_I_t(double t, AbstractCoupledModel < T, U, V, W >* model,
-              unsigned int index) : IN_SC_t < T, U, V, W >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V, typename W >
-struct IN_SC_B_t : public IN_SC_t < T, U, V , W >
-{
-    IN_SC_B_t(double t, AbstractCoupledModel < T, U, V, W >* model,
-              unsigned int index) : IN_SC_t < T, U, V, W >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V, typename W >
-struct OUT_SC_t : public SC_t < T, U, V , W >
-{
-    OUT_SC_t(double t, AbstractCoupledModel < T, U, V, W >* model,
-             unsigned int index) : SC_t < T, U, V, W >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V, typename W >
-struct OUT_SC_I_t : public OUT_SC_t < T, U, V , W >
-{
-    OUT_SC_I_t(double t, AbstractCoupledModel < T, U, V, W >* model,
-               unsigned int index) : OUT_SC_t < T, U, V, W >(t, model, index)
-    { }
-};
-
-template < typename T, typename U, typename V, typename W >
-struct OUT_SC_B_t : public SC_t < T, U, V , W >
-{
-    OUT_SC_B_t(double t, AbstractCoupledModel < T, U, V, W >* model,
-               unsigned int index) : OUT_SC_t < T, U, V, W >(t, model, index)
-    { }
-};
-
-template < typename T >
-struct OUT_A_t
-{
-    OUT_A_t(double t, T value) : t(t), value(value)
-    { }
-
-    double t;
-    T value;
-};
-
-template < typename T >
-struct OUT_A_I_t
-{
-    OUT_A_I_t(int t, T value) : t(t), value(value)
-    { }
-
-    int t;
-    T value;
-};
-
-template < typename T >
-struct OUT_A_B_t
-{
-    OUT_A_B_t(bool t, T value) : t(t), value(value)
-    { }
-
-    bool t;
-    T value;
-};
-
-template < typename T, typename U, typename V, typename W >
-IN_SC_t < T, U, V, W > IN(double t, AbstractCoupledModel < T, U, V, W >* model,
-                       unsigned int index)
-{ return IN_SC_t < T, U, V, W >(t, model, index); }
-
-template < typename T, typename U, typename V, typename W >
-IN_SC_I_t < T, U, V, W > IN_I(double t,
-                              AbstractCoupledModel < T, U, V, W >* model,
-                              unsigned int index)
-{ return IN_SC_I_t < T, U, V, W >(t, model, index); }
-
-template < typename T, typename U, typename V, typename W >
-IN_SC_B_t < T, U, V, W > IN_B(double t,
-                              AbstractCoupledModel < T, U, V, W >* model,
-                              unsigned int index)
-{ return IN_SC_B_t < T, U, V, W >(t, model, index); }
-
-template < typename T, typename U, typename V, typename W >
-OUT_SC_t < T, U, V, W > OUT(double t,
-                            AbstractCoupledModel < T, U, V, W >* model,
-                            unsigned int index)
-{ return OUT_SC_t < T, U, V, W >(t, model, index); }
-
-template < typename T, typename U, typename V, typename W >
-OUT_SC_I_t < T, U, V, W > OUT_I(double t,
-                                AbstractCoupledModel < T, U, V, W >* model,
-                                unsigned int index)
-{ return OUT_SC_I_t < T, U, V, W >(t, model, index); }
-
-template < typename T, typename U, typename V, typename W >
-OUT_SC_B_t < T, U, V, W > OUT_B(double t,
-                                AbstractCoupledModel < T, U, V, W >* model,
-                                unsigned int index)
-{ return OUT_SC_B_t < T, U, V, W >(t, model, index); }
-
-template < typename T >
-OUT_A_t < T > OUT(double t, T value)
-{ return OUT_A_t < T >(t, value); }
-
-template < typename T >
-OUT_A_I_t < T > OUT_I(double t, T value)
-{ return OUT_A_I_t < T >(t, value); }
-
-template < typename T >
-OUT_A_B_t < T > OUT_B(double t, T value)
-{ return OUT_A_B_t < T >(t, value); }
-
-template < typename T1, typename U1, typename V1, typename W1,
-           typename T2, typename U2, typename V2, typename W2 >
-void operator>>(OUT_SC_t < T2, U2, V2, W2 > out, IN_SC_t < T1, U1, V1, W1 > in)
-{
-  if (out.model->is_computed(out.t, out.index)) {
-    in.model->put(in.t, in.index, out.model->get(out.t, out.index));
-  }
-}
-
-template < typename T1, typename U1, typename V1, typename W1,
-           typename T2, typename U2, typename V2, typename W2 >
-void operator>>(OUT_SC_I_t < T2, U2, V2, W2 > out,
-                IN_SC_I_t < T1, U1, V1, W1 > in)
-{
-  if (out.model->is_computed(out.t, out.index)) {
-    in.model->put(in.t, in.index, out.model->getI(out.t, out.index));
-  }
-}
-
-template < typename T1, typename U1, typename V1, typename W1,
-           typename T2, typename U2, typename V2, typename W2 >
-void operator>>(OUT_SC_B_t < T2, U2, V2, W2 > out,
-                IN_SC_B_t < T1, U1, V1, W1 > in)
-{
-  if (out.model->is_computed(out.t, out.index)) {
-    in.model->put(in.t, in.index, out.model->getB(out.t, out.index));
-  }
-}
-
-template < typename T, typename U, typename V, typename W, typename Z >
-void operator>>(OUT_A_t < Z > out, IN_SC_t < T, U, V, W > in)
-{ in.model->put(in.t, in.index, out.value); }
-
-template < typename T, typename U, typename V, typename W, typename Z >
-void operator>>(OUT_A_I_t < Z > out, IN_SC_I_t < T, U, V, W > in)
-{ in.model->put(in.t, in.index, out.value); }
-
-template < typename T, typename U, typename V, typename W, typename Z >
-void operator>>(OUT_A_B_t < Z > out, IN_SC_B_t < T, U, V, W > in)
-{ in.model->put(in.t, in.index, out.value); }
-
 } }
 
 #endif

+ 4 - 0
src/artis/kernel/AbstractModel.hpp

@@ -50,6 +50,8 @@ public:
 
     virtual void after(typename U::type t) = 0;
 
+    virtual const Node < U >* atomic(unsigned int index) const = 0;
+
     virtual void before(typename U::type t) = 0;
 
     virtual bool check(typename U::type /* t */) const
@@ -59,6 +61,8 @@ public:
 
     virtual void init(typename U::type t, const V& parameters) = 0;
 
+    virtual bool is_atomic() const = 0;
+
     virtual bool is_computed(typename U::type t) const
     { return last_time == t; }
 

+ 27 - 0
src/artis/kernel/Builder.cpp

@@ -0,0 +1,27 @@
+/**
+ * @file artis/kernel/Builder.cpp
+ * @author See the AUTHORS file
+ */
+
+/*
+ * Copyright (C) 2012-2016 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <artis/kernel/Builder.hpp>
+
+namespace artis { namespace kernel {
+
+} }

+ 61 - 0
src/artis/kernel/Builder.hpp

@@ -0,0 +1,61 @@
+/**
+ * @file artis/kernel/Simulator.hpp
+ * @author See the AUTHORS file
+ */
+
+/*
+ * Copyright (C) 2012-2016 ULCO http://www.univ-littoral.fr
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ARTIS_KERNEL_BUILDER_HPP
+#define ARTIS_KERNEL_BUILDER_HPP
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+
+#include <artis/kernel/AbstractCoupledModel.hpp>
+
+#include <sstream>
+
+namespace artis { namespace kernel {
+
+template < typename T, typename U, typename V, typename W >
+class Builder
+{
+public:
+    Builder(const std::string& json)
+    {
+        std::stringstream ss;
+
+        ss << json;
+        boost::property_tree::read_json(ss, pt);
+    }
+
+    virtual ~Builder()
+    { }
+
+    artis::kernel::AbstractCoupledModel < T, U, V, W >* build()
+    {
+        return 0;
+    }
+
+private:
+    boost::property_tree::ptree pt;
+};
+
+} }
+
+#endif

+ 25 - 104
src/artis/kernel/Externals.hpp

@@ -31,11 +31,6 @@ namespace artis { namespace kernel {
 template < typename T, typename U >
 class Externals
 {
-    struct Var
-    {
-
-    };
-
 public:
     Externals() : updated(false)
     { }
@@ -48,127 +43,55 @@ public:
         bool OK = true;
         typename std::vector <
             std::pair < double,
-                        double T::* > >::const_iterator it = externalsD.begin();
+                        Any > >::const_iterator it = externals.begin();
 
-        while (it != externalsD.end() and OK) {
+        while (it != externals.end() and OK) {
             OK = it->first == t;
             ++it;
         }
         return OK;
     }
 
+    template < typename V >
     void E(std::initializer_list < std::pair < unsigned int,
-           bool T::* > > externals)
+           V T::* > > list)
     {
         for (typename std::initializer_list < std::pair < unsigned int,
-                 bool T::* > >::iterator it =
-                 externals.begin(); it != externals.end(); ++it) {
-            if (externalsB.size() <= it->first) {
-                externalsB.resize(it->first + 1);
+                 V T::* > >::iterator it = list.begin(); it != list.end();
+             ++it) {
+            if (externals.size() <= it->first) {
+                externals.resize(it->first + 1);
             }
-            externalsB[it->first] = std::make_pair(-1, it->second);
-        }
-    }
-
-    void E(std::initializer_list < std::pair < unsigned int,
-           int T::* > > externals)
-    {
-        for (typename std::initializer_list < std::pair < unsigned int,
-                 int T::* > >::iterator it =
-                 externals.begin(); it != externals.end(); ++it) {
-            if (externalsI.size() <= it->first) {
-                externalsI.resize(it->first + 1);
-            }
-            externalsI[it->first] = std::make_pair(-1, it->second);
-        }
-    }
-
-    void E(std::initializer_list < std::pair < unsigned int,
-           double T::* > > externals)
-    {
-        for (typename std::initializer_list < std::pair < unsigned int,
-                 double T::* > >::iterator it =
-                 externals.begin(); it != externals.end(); ++it) {
-            if (externalsD.size() <= it->first) {
-                externalsD.resize(it->first + 1);
-            }
-            externalsD[it->first] = std::make_pair(-1, it->second);
-        }
-    }
-
-    void externalB(unsigned int index, bool T::* var)
-    {
-        if (externalsB.size() <= index) {
-            externalsB.resize(index + 1);
+            externals[it->first] = std::make_pair(-1, it->second);
         }
-        externalsB[index] = std::make_pair(-1, var);
     }
 
-    void externalI(unsigned int index, int T::* var)
+    template < typename V >
+    void external(unsigned int index, V T::* var)
     {
-        if (externalsI.size() <= index) {
-            externalsI.resize(index + 1);
+        if (externals.size() <= index) {
+            externals.resize(index + 1);
         }
-        externalsI[index] = std::make_pair(-1, var);
+        externals[index] = std::make_pair(-1, var);
     }
 
-    void external(unsigned int index, double T::* var)
-    {
-        if (externalsD.size() <= index) {
-            externalsD.resize(index + 1);
-        }
-        externalsD[index] = std::make_pair(-1, var);
-    }
-
-    bool is_readyB(typename U::type t, unsigned int index) const
-    { return externalsB.at(index).first == t; }
-
-    bool is_readyI(typename U::type t, unsigned int index) const
-    { return externalsI.at(index).first == t; }
-
     bool is_ready(typename U::type t, unsigned int index) const
-    { return externalsD.at(index).first == t; }
+    { return externals.at(index).first == t; }
 
-    void put(typename U::type t, unsigned int index, bool value)
+    template < typename V >
+    void put(typename U::type t, unsigned int index, V value)
     {
-        if (externalsB.at(index).first != t) {
-            static_cast < T* >(this)->*externalsB.at(index).second = value;
-            externalsB.at(index).first = t;
-            updated = true;
-        } else {
-            if (static_cast < T* >(this)->*externalsB.at(index).second !=
-                value) {
-                static_cast < T* >(this)->*externalsB.at(index).second = value;
-                updated = true;
-            }
-        }
-    }
+        if (externals.at(index).first != t) {
+            Any v = externals.at(index).second;
 
-    void put(typename U::type t, unsigned int index, int value)
-    {
-        if (externalsI.at(index).first != t) {
-            static_cast < T* >(this)->*externalsI.at(index).second = value;
-            externalsI.at(index).first = t;
+            v.put < T, V >(static_cast < T* >(this), value);
+            externals.at(index).first = t;
             updated = true;
         } else {
-            if (static_cast < T* >(this)->*externalsI.at(index).second !=
-                value) {
-                static_cast < T* >(this)->*externalsI.at(index).second = value;
-                updated = true;
-            }
-        }
-    }
+            Any v = externals.at(index).second;
 
-    void put(typename U::type t, unsigned int index, double value)
-    {
-        if (externalsD.at(index).first != t) {
-            static_cast < T* >(this)->*externalsD.at(index).second = value;
-            externalsD.at(index).first = t;
-            updated = true;
-        } else {
-            if (static_cast < T* >(this)->*externalsD.at(index).second !=
-                value) {
-                static_cast < T* >(this)->*externalsD.at(index).second = value;
+            if (static_cast < const T* >(this)->*(v.get < T, V >()) != value) {
+                v.put < T, V >(static_cast < T* >(this), value);
                 updated = true;
             }
         }
@@ -176,9 +99,7 @@ public:
 
 protected:
     bool updated;
-    std::vector < std::pair < typename U::type, bool T::* > > externalsB;
-    std::vector < std::pair < typename U::type, int T::* > > externalsI;
-    std::vector < std::pair < typename U::type, double T::* > > externalsD;
+    std::vector < std::pair < typename U::type, Any > > externals;
 };
 
 } } // namespace artis kernel

+ 57 - 103
src/artis/kernel/Internals.hpp

@@ -24,6 +24,8 @@
 #define __ARTIS_KERNEL_INTERNALS_HPP
 
 #include <artis/kernel/State.hpp>
+#include <artis/kernel/Value.hpp>
+
 #include <vector>
 
 namespace artis { namespace kernel {
@@ -38,128 +40,80 @@ public:
     virtual ~Internals()
     { }
 
-    bool T::* getB(unsigned int index) const
-    { return internalsB.at(index); }
-
-    int T::* getI(unsigned int index) const
-    { return internalsI.at(index); }
-
-    double T::* get(unsigned int index) const
-    { return internalsD.at(index); }
+    const Any& get(unsigned int index) const
+    { return internals.at(index); }
 
+    template < typename V >
     void I(std::initializer_list < std::pair < unsigned int,
-           bool T::* > > internals)
+           V T::* > > list)
     {
         for (typename std::initializer_list < std::pair < unsigned int,
-                 bool T::* > >::iterator it =
-                 internals.begin(); it != internals.end(); ++it) {
-            if (internalsB.size() <= it->first) {
-                internalsB.resize(it->first + 1);
+                 V T::* > >::iterator it = list.begin(); it != list.end();
+             ++it) {
+            if (internals.size() <= it->first) {
+                internals.resize(it->first + 1);
             }
-            internalsB[it->first] = it->second;
+            internals[it->first] = it->second;
         }
     }
 
-    void I(std::initializer_list < std::pair < unsigned int,
-           int T::* > > internals)
+    template < typename V >
+    void internal(unsigned int index, V T::* var)
     {
-        for (typename std::initializer_list < std::pair < unsigned int,
-                 int T::* > >::iterator it =
-                 internals.begin(); it != internals.end(); ++it) {
-            if (internalsI.size() <= it->first) {
-                internalsI.resize(it->first + 1);
-            }
-            internalsI[it->first] = it->second;
+        if (internals.size() <= index) {
+            internals.resize(index + 1);
         }
+        internals[index] = Any(var);
     }
 
-    void I(std::initializer_list < std::pair < unsigned int,
-           double T::* > > internals)
+    virtual void restore(const State < U >& /* state */)
     {
-        for (typename std::initializer_list < std::pair < unsigned int,
-                 double T::* > >::iterator it =
-                 internals.begin(); it != internals.end(); ++it) {
-            if (internalsD.size() <= it->first) {
-                internalsD.resize(it->first + 1);
-            }
-            internalsD[it->first] = it->second;
-        }
-    }
-
-    void internalB(unsigned int index, bool T::* var)
-    {
-        if (internalsB.size() <= index) {
-            internalsB.resize(index + 1);
-        }
-        internalsB[index] = var;
+        // unsigned int index = 0;
+
+        // for (typename std::vector < Any >::iterator it =
+        //          internals.begin(); it != internals.end(); ++it) {
+        //     state.get_internal(index, *it);
+        //     ++index;
+        // }
+        // index = 0;
+        // for (typename std::vector < int T::* >::iterator it =
+        //          internalsI.begin(); it != internalsI.end(); ++it) {
+        //     state.get_internal(index, *it);
+        //     ++index;
+        // }
+        // index = 0;
+        // for (typename std::vector < double T::* >::iterator it =
+        //          internalsD.begin(); it != internalsD.end(); ++it) {
+        //     state.get_internal(index, *it);
+        //     ++index;
+        // }
     }
 
-    void internalI(unsigned int index, int T::* var)
+    virtual void save(State < U >& /* state */) const
     {
-        if (internalsI.size() <= index) {
-            internalsI.resize(index + 1);
-        }
-        internalsI[index] = var;
-    }
-
-    void internal(unsigned int index, double T::* var)
-    {
-        if (internalsD.size() <= index) {
-            internalsD.resize(index + 1);
-        }
-        internalsD[index] = var;
-    }
-
-    virtual void restore(const State < U >& state)
-    {
-        unsigned int index = 0;
-
-        for (typename std::vector < bool T::* >::iterator it =
-                 internalsB.begin(); it != internalsB.end(); ++it) {
-            state.get_internal(index, *it);
-            ++index;
-        }
-        index = 0;
-        for (typename std::vector < int T::* >::iterator it =
-                 internalsI.begin(); it != internalsI.end(); ++it) {
-            state.get_internal(index, *it);
-            ++index;
-        }
-        index = 0;
-        for (typename std::vector < double T::* >::iterator it =
-                 internalsD.begin(); it != internalsD.end(); ++it) {
-            state.get_internal(index, *it);
-            ++index;
-        }
-    }
-
-    virtual void save(State < U >& state) const
-    {
-        unsigned int index = 0;
-
-        for (typename std::vector < bool T::* >::const_iterator it =
-                 internalsB.begin(); it != internalsB.end(); ++it) {
-            state.add_internal(index, *it);
-            ++index;
-        }
-        index = 0;
-        for (typename std::vector < int T::* >::const_iterator it =
-                 internalsI.begin(); it != internalsI.end(); ++it) {
-            state.add_internal(index, *it);
-            ++index;
-        }
-        index = 0;
-        for (typename std::vector < double T::* >::const_iterator it =
-                 internalsD.begin(); it != internalsD.end(); ++it) {
-            state.add_internal(index, *it);
-            ++index;
-        }
+        // unsigned int index = 0;
+
+        // for (typename std::vector < bool T::* >::const_iterator it =
+        //          internalsB.begin(); it != internalsB.end(); ++it) {
+        //     state.add_internal(index, *it);
+        //     ++index;
+        // }
+        // index = 0;
+        // for (typename std::vector < int T::* >::const_iterator it =
+        //          internalsI.begin(); it != internalsI.end(); ++it) {
+        //     state.add_internal(index, *it);
+        //     ++index;
+        // }
+        // index = 0;
+        // for (typename std::vector < double T::* >::const_iterator it =
+        //          internalsD.begin(); it != internalsD.end(); ++it) {
+        //     state.add_internal(index, *it);
+        //     ++index;
+        // }
     }
 
 private:
-    std::vector < bool T::* > internalsB;
-    std::vector < int T::* > internalsI;
-    std::vector < double T::* > internalsD;
+    std::vector < Any > internals;
 };
 
 } } // namespace artis kernel

+ 5 - 4
src/artis/kernel/Node.hpp

@@ -23,6 +23,8 @@
 #ifndef __ARTIS_KERNEL_NODE_HPP
 #define __ARTIS_KERNEL_NODE_HPP
 
+#include <artis/kernel/Value.hpp>
+
 #include <cassert>
 
 namespace artis { namespace kernel {
@@ -37,11 +39,10 @@ public:
     virtual ~Node()
     { }
 
-    virtual double get(typename U::type t, unsigned int index) const = 0;
-
-    virtual int getI(typename U::type t, unsigned int index) const = 0;
+    virtual const Any& get(typename U::type t, unsigned int index) const = 0;
 
-    virtual bool getB(typename U::type t, unsigned int index) const = 0;
+    virtual std::string get(const ValueType& value_type, typename U::type t,
+                            unsigned int index) const = 0;
 
     virtual const Node < U >* get_submodel(unsigned int /* index */) const
     {

+ 91 - 0
src/artis/kernel/Value.hpp

@@ -26,11 +26,102 @@
 #include <boost/serialization/serialization.hpp>
 #include <boost/serialization/array.hpp>
 
+#include <algorithm>
 #include <cstring>
 #include <typeinfo>
 
+#include <iostream>
+
 namespace artis { namespace kernel {
 
+enum ValueType { DOUBLE, INT, BOOL };
+
+class Any
+{
+private:
+    struct base
+    {
+        virtual ~base() { }
+        virtual base* clone() const = 0;
+    };
+
+    template < typename T, typename V >
+    struct data : base
+    {
+        data(V T::* const& value) : value_(value)
+        { }
+
+        base* clone() const { return new data < T, V >(*this); }
+
+        V T::* value_;
+    };
+
+    base* ptr_;
+
+public:
+    Any() : ptr_(nullptr)
+    { }
+
+    template < typename T, typename V >
+    Any(V T::* const& value) : ptr_(new data < T, V >(value))
+    { }
+
+    Any(Any const& other) : ptr_(other.ptr_? other.ptr_->clone() : nullptr)
+    { }
+
+    virtual ~Any()
+    { if (this->ptr_) delete this->ptr_; }
+
+    void operator=(Any const& other)
+    { Any(other).swap(*this); }
+
+    void swap(Any& other)
+    { std::swap(this->ptr_, other.ptr_); }
+
+    template < typename T, typename V >
+    V T::* get() const
+    { return dynamic_cast < data < T, V >* >(ptr_)->value_; }
+
+    template < typename T, typename V >
+    void put(T* o, const V& value )
+    {
+        V T::* p = dynamic_cast <
+            data < T, V >* >(ptr_)->value_;
+        o->*(p) = value;
+    }
+
+    template < typename T >
+    std::string to_string(const T* o) const
+    {
+        if (ptr_) {
+            try {
+                double T::* p = dynamic_cast <
+                    data < T, double >* >(ptr_)->value_;
+
+                return std::to_string(o->*(p));
+            } catch(...) {
+                try {
+                    int T::* p = dynamic_cast <
+                        data < T, int >* >(this->ptr_)->value_;
+
+                    return std::to_string(o->*(p));
+                } catch(...) {
+                    try {
+                        bool T::* p = dynamic_cast <
+                            data < T, bool >* >(this->ptr_)->value_;
+
+                        return std::to_string(o->*(p));
+                    } catch(...) {
+                        return "NA";
+                    }
+                }
+            }
+        } else {
+            return "NA";
+        }
+    }
+};
+
 class Value
 {
 public:

+ 18 - 58
src/artis/observer/View.hpp

@@ -24,8 +24,11 @@
 #define ARTIS_OBSERVER_VIEW_HPP
 
 #include <artis/kernel/AbstractModel.hpp>
+#include <artis/kernel/Value.hpp>
 #include <artis/utils/DoubleTime.hpp>
 
+#include <boost/lexical_cast.hpp>
+
 namespace artis { namespace observer {
 
 template < typename U, typename V >
@@ -34,7 +37,7 @@ class View
     typedef std::vector < unsigned int > Selector;
 
 public:
-    typedef std::vector < std::pair < double, double > > Value;
+    typedef std::vector < std::pair < double, std::string > > Value;
     typedef std::map < std::string, Value > Values;
 
     View() : _model(0)
@@ -103,7 +106,8 @@ public:
                 ++itp;
             }
             if (itp != it->second.end()) {
-                return itp->second;
+                // TODO: to improve
+                return boost::lexical_cast < double >(itp->second);
             } else {
                 return 0;
             }
@@ -124,74 +128,31 @@ public:
 
     virtual void observe(double time)
     {
-        for (Selectors::const_iterator it = _selectors.begin();
+        for (typename Selectors::const_iterator it = _selectors.begin();
              it != _selectors.end(); ++it) {
             const kernel::Node < utils::DoubleTime >* model = _model;
 
-            if (it->second.size() > 1) {
-                size_t i = 0;
-
-                while (i < it->second.size() - 1 and model) {
-                    model = model->get_submodel(it->second[i]);
-                    ++i;
-                }
-            }
-            if (model) {
-                _values[it->first].push_back(
-                    std::make_pair(time, model->get(time, it->second.back())));
-            }
-        }
-        for (Selectors::const_iterator it = _selectorsI.begin();
-             it != _selectorsI.end(); ++it) {
-            const kernel::Node < utils::DoubleTime >* model = _model;
-
-            if (it->second.size() > 1) {
+            if (it->second.second.size() > 1) {
                 size_t i = 0;
 
-                while (i < it->second.size() - 1 and model) {
-                    model = model->get_submodel(it->second[i]);
+                while (i < it->second.second.size() - 1 and model) {
+                    model = model->get_submodel(it->second.second[i]);
                     ++i;
                 }
             }
             if (model) {
                 _values[it->first].push_back(
-                    std::make_pair(time, model->getI(time, it->second.back())));
+                    std::make_pair(time,
+                                   model->get(it->second.first, time,
+                                              it->second.second.back())));
             }
         }
-        for (Selectors::const_iterator it = _selectorsB.begin();
-             it != _selectorsB.end(); ++it) {
-            const kernel::Node < utils::DoubleTime >* model = _model;
-
-            if (it->second.size() > 1) {
-                size_t i = 0;
-
-                while (i < it->second.size() - 1 and model) {
-                    model = model->get_submodel(it->second[i]);
-                    ++i;
-                }
-            }
-            if (model) {
-                _values[it->first].push_back(
-                    std::make_pair(time, model->getB(time, it->second.back())));
-            }
-        }
-    }
-
-    void selectorI(const std::string& name, const Selector& chain)
-    {
-        _selectorsI[name] = chain;
-        _values[name] = Value();
-    }
-
-    void selectorB(const std::string& name, const Selector& chain)
-    {
-        _selectorsB[name] = chain;
-        _values[name] = Value();
     }
 
-    void selector(const std::string& name, const Selector& chain)
+    void selector(const std::string& name, kernel::ValueType value_type,
+                  const Selector& chain)
     {
-        _selectors[name] = chain;
+        _selectors[name] = std::make_pair(value_type, chain);
         _values[name] = Value();
     }
 
@@ -199,11 +160,10 @@ public:
     { return _values;}
 
 private:
-    typedef std::map < std::string, Selector > Selectors;
+    typedef std::map < std::string, std::pair < kernel::ValueType,
+                                                Selector > > Selectors;
 
     Selectors                                    _selectors;
-    Selectors                                    _selectorsI;
-    Selectors                                    _selectorsB;
     Values                                       _values;
     const artis::kernel::AbstractModel < U, V >* _model;
 };

+ 23 - 26
src/test/test.cpp

@@ -50,14 +50,12 @@ class AModel : public AtomicModel < AModel >
 public:
     enum externals { };
 
-    enum internalsB { BX };
-    enum internalsI { IX };
-    enum internals { DX };
+    enum internals { DX, BX, IX };
 
     AModel()
     {
-        internalI(IX, &AModel::_ix);
-        internalB(BX, &AModel::_bx);
+        internal(IX, &AModel::_ix);
+        internal(BX, &AModel::_bx);
         internal(DX, &AModel::_dx);
     }
 
@@ -87,22 +85,21 @@ private:
 class BModel : public AtomicModel < BModel >
 {
 public:
-    enum externalsB { BX };
-    enum externalsI { IX };
-    enum externals { DX };
-
-    enum internalsB { BY };
-    enum internalsI { IY };
-    enum internals { DY };
+    enum externals { IX, BX, DX };
+    enum internals { IY, BY, DY };
 
     BModel()
     {
-        externalI(IX, &BModel::_ix);
-        externalB(BX, &BModel::_bx);
+        // external(IX, &BModel::_ix);
+        E < int >({ { IX, &BModel::_ix } });
+
+        external(BX, &BModel::_bx);
         external(DX, &BModel::_dx);
 
-        internalI(IY, &BModel::_iy);
-        internalB(BY, &BModel::_by);
+        // internal(IY, &BModel::_iy);
+        I < int >({ { IY, &BModel::_iy } });
+
+        internal(BY, &BModel::_by);
         internal(DY, &BModel::_dy);
     }
 
@@ -111,7 +108,6 @@ public:
 
     void compute(double /* t */, bool update)
     {
-
         if (update)
             std::cout << "UPDATE" << std::endl;
 
@@ -159,9 +155,10 @@ public:
     void compute(double t, bool /* update */)
     {
         _a(t);
-        OUT_I(t, &_a, AModel::IX) >> IN_I(t, &_b, BModel::IX);
-        OUT_B(t, &_a, AModel::BX) >> IN_B(t, &_b, BModel::BX);
-        OUT(t, &_a, AModel::DX) >> IN(t, &_b, BModel::DX);
+
+        _b.put < double >(t, BModel::DX, _a.get < double >(t, AModel::DX));
+        _b.put < int >(t, BModel::IX, _a.get < int >(t, AModel::IX));
+        _b.put < bool >(t, BModel::BX, _a.get < bool >(t, AModel::BX));
         _b(t);
     }
 
@@ -192,12 +189,12 @@ class AView : public artis::observer::View < artis::utils::DoubleTime,
 public:
     AView()
     {
-        selectorI("A::I", { RootModel::A, AModel::IX });
-        selectorB("A::B", { RootModel::A, AModel::BX });
-        selector("A::D", { RootModel::A, AModel::DX });
-        selectorI("B::I", { RootModel::B, BModel::IY });
-        selectorB("B::B", { RootModel::B, BModel::BY });
-        selector("B::D", { RootModel::B, BModel::DY });
+        selector("A::I", INT, { RootModel::A, AModel::IX });
+        selector("A::B", BOOL, { RootModel::A, AModel::BX });
+        selector("A::D", DOUBLE, { RootModel::A, AModel::DX });
+        selector("B::I", INT, { RootModel::B, BModel::IY });
+        selector("B::B", BOOL, { RootModel::B, BModel::BY });
+        selector("B::D", DOUBLE, { RootModel::B, BModel::DY });
     }
 
     virtual ~AView()