Sfoglia il codice sorgente

Add trace with variable name

Eric Ramat 7 anni fa
parent
commit
530790b07c

+ 4 - 2
src/artis/kernel/AbstractAtomicModel.hpp

@@ -68,7 +68,8 @@ public:
                 utils::Trace < utils::DoubleTime >::trace()
                     << utils::TraceElement < utils::DoubleTime >("KERNEL", t,
                                                                  utils::KERNEL)
-                    << i << " = " << Internals < T, U >::get(i).to_string(
+                    << Internals < T, U >::name(i) << " = "
+                    << Internals < T, U >::get(i).to_string(
                         dynamic_cast < const T* >(this));
                 utils::Trace < utils::DoubleTime >::trace().flush();
             }
@@ -94,7 +95,8 @@ public:
                 utils::Trace < utils::DoubleTime >::trace()
                     << utils::TraceElement < utils::DoubleTime >("KERNEL", t,
                                                                  utils::KERNEL)
-                    << i << " = " << Internals < T, U >::get(i).to_string(
+                    << Internals < T, U >::name(i) << " = "
+                    << Internals < T, U >::get(i).to_string(
                         dynamic_cast < const T* >(this));
                 utils::Trace < utils::DoubleTime >::trace().flush();
             }

+ 59 - 22
src/artis/kernel/AbstractCoupledModel.hpp

@@ -49,14 +49,18 @@ class AbstractCoupledModel : public AbstractModel < U, V >,
     typedef std::map < int, std::pair < type*,
                                         int > > SubModelInternals;
 
+public:
     struct Var
     {
         unsigned int index;
         type* model;
         int sub_index;
+
+        Var (unsigned int index, type* model, int sub_index) :
+            index(index), model(model), sub_index(sub_index)
+        { }
     };
 
-public:
     AbstractCoupledModel(const type* parent = 0) : type(parent)
     { }
 
@@ -73,12 +77,13 @@ public:
             << "AFTER - "
             << AbstractCoupledModel < T, U, V, W >::path(this);
         utils::Trace < utils::DoubleTime >::trace().flush();
-                for (size_t i = 0; i < Internals < T, U >::size(); ++i) {
+        for (size_t i = 0; i < Internals < T, U >::size(); ++i) {
             if (not Internals < T, U >::get(i).is_null()) {
                 utils::Trace < utils::DoubleTime >::trace()
                     << utils::TraceElement < utils::DoubleTime >("KERNEL", t,
                                                                  utils::KERNEL)
-                    << i << " = " << Internals < T, U >::get(i).to_string(
+                    << Internals < T, U >::name(i) << " = "
+                    << Internals < T, U >::get(i).to_string(
                         dynamic_cast < const T* >(this));
                 utils::Trace < utils::DoubleTime >::trace().flush();
             }
@@ -111,12 +116,13 @@ public:
             << "BEFORE - "
             << AbstractCoupledModel < T, U, V, W >::path(this);
         utils::Trace < utils::DoubleTime >::trace().flush();
-                for (size_t i = 0; i < Internals < T, U >::size(); ++i) {
+        for (size_t i = 0; i < Internals < T, U >::size(); ++i) {
             if (not Internals < T, U >::get(i).is_null()) {
                 utils::Trace < utils::DoubleTime >::trace()
                     << utils::TraceElement < utils::DoubleTime >("KERNEL", t,
                                                                  utils::KERNEL)
-                    << i << " = " << Internals < T, U >::get(i).to_string(
+                    << Internals < T, U >::name(i) << " = "
+                    << Internals < T, U >::get(i).to_string(
                         dynamic_cast < const T* >(this));
                 utils::Trace < utils::DoubleTime >::trace().flush();
             }
@@ -360,21 +366,13 @@ protected:
         Internals < T, U >::internalB(index, var);
     }
 
-    void internal(unsigned int index, double T::* var)
-    { Internals < T, U >::internal(index, var); }
-
-    void internal(unsigned int index, type* model, int sub_index)
+    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)
+    void I_(std::initializer_list < Var > internals)
     {
         for (typename std::initializer_list < Var >::iterator it =
                  internals.begin(); it != internals.end(); ++it) {
@@ -383,8 +381,8 @@ protected:
         }
     }
 
-    void S(std::initializer_list < std::pair <  unsigned int,
-           type* > > models)
+    void SM_(std::initializer_list < std::pair <  unsigned int,
+             type* > > models)
     {
         for (typename std::initializer_list < std::pair <  unsigned int,
                  type* > >::iterator it =
@@ -394,11 +392,6 @@ protected:
         }
     }
 
-    template < typename Z >
-    void S(std::initializer_list < std::pair < unsigned int,
-           Z T::* > > list)
-    { States < T, U >::S(list); }
-
     void setsubmodel(unsigned int index, type* model)
     {
         if (setsubmodels.find(index) == setsubmodels.end()) {
@@ -414,6 +407,50 @@ private:
     Setsubmodels setsubmodels;
 };
 
+#define InternalS(index, var, sub_index) internal_(index, var, sub_index)
+
+#define ITEM_S(index, var, sub_index) Var(index, var, sub_index)
+#define UNWRAP_ITEM_S(...) ITEM_S __VA_ARGS__
+#define LIST_S_16(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15, L16) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8), UNWRAP_ITEM_S(L9), UNWRAP_ITEM_S(L10), UNWRAP_ITEM_S(L11), UNWRAP_ITEM_S(L12), UNWRAP_ITEM_S(L13), UNWRAP_ITEM_S(L14), UNWRAP_ITEM_S(L15), UNWRAP_ITEM_S(L16) }
+#define LIST_S_15(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8), UNWRAP_ITEM_S(L9), UNWRAP_ITEM_S(L10), UNWRAP_ITEM_S(L11), UNWRAP_ITEM_S(L12), UNWRAP_ITEM_S(L13), UNWRAP_ITEM_S(L14), UNWRAP_ITEM_S(L15) }
+#define LIST_S_14(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8), UNWRAP_ITEM_S(L9), UNWRAP_ITEM_S(L10), UNWRAP_ITEM_S(L11), UNWRAP_ITEM_S(L12), UNWRAP_ITEM_S(L13), UNWRAP_ITEM_S(L14) }
+#define LIST_S_13(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8), UNWRAP_ITEM_S(L9), UNWRAP_ITEM_S(L10), UNWRAP_ITEM_S(L11), UNWRAP_ITEM_S(L12), UNWRAP_ITEM_S(L13) }
+#define LIST_S_12(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8), UNWRAP_ITEM_S(L9), UNWRAP_ITEM_S(L10), UNWRAP_ITEM_S(L11), UNWRAP_ITEM_S(L12) }
+#define LIST_S_11(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8), UNWRAP_ITEM_S(L9), UNWRAP_ITEM_S(L10), UNWRAP_ITEM_S(L11) }
+#define LIST_S_10(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8), UNWRAP_ITEM_S(L9), UNWRAP_ITEM_S(L10) }
+#define LIST_S_9(L1, L2, L3, L4, L5, L6, L7, L8, L9) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8), UNWRAP_ITEM_S(L9) }
+#define LIST_S_8(L1, L2, L3, L4, L5, L6, L7, L8) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7), UNWRAP_ITEM_S(L8) }
+#define LIST_S_7(L1, L2, L3, L4, L5, L6, L7) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6), UNWRAP_ITEM_S(L7) }
+#define LIST_S_6(L1, L2, L3, L4, L5, L6) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5), UNWRAP_ITEM_S(L6) }
+#define LIST_S_5(L1, L2, L3, L4, L5) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4), UNWRAP_ITEM_S(L5) }
+#define LIST_S_4(L1, L2, L3, L4) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3), UNWRAP_ITEM_S(L4) }
+#define LIST_S_3(L1, L2, L3) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2), UNWRAP_ITEM_S(L3) }
+#define LIST_S_2(L1, L2) { UNWRAP_ITEM_S(L1), UNWRAP_ITEM_S(L2) }
+#define LIST_S_1(L1) { UNWRAP_ITEM_S(L1) }
+#define UNWRAP_S_2(...) GET_MACRO(__VA_ARGS__, LIST_S_16, LIST_S_15, LIST_S_14, LIST_S_13, LIST_S_12, LIST_S_11, LIST_S_10, LIST_S_9, LIST_S_8, LIST_S_7, LIST_S_6, LIST_S_5, LIST_S_4, LIST_S_3, LIST_S_2, LIST_S_1)(__VA_ARGS__)
+#define InternalsS(L) I_(UNWRAP_S_2 L)
+
+#define ITEM_Sub(index, model) { index, model }
+#define UNWRAP_ITEM_Sub(...) ITEM_Sub __VA_ARGS__
+#define LIST_Sub_16(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15, L16) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8), UNWRAP_ITEM_Sub(L9), UNWRAP_ITEM_Sub(L10), UNWRAP_ITEM_Sub(L11), UNWRAP_ITEM_Sub(L12), UNWRAP_ITEM_Sub(L13), UNWRAP_ITEM_Sub(L14), UNWRAP_ITEM_Sub(L15), UNWRAP_ITEM_Sub(L16) }
+#define LIST_Sub_15(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8), UNWRAP_ITEM_Sub(L9), UNWRAP_ITEM_Sub(L10), UNWRAP_ITEM_Sub(L11), UNWRAP_ITEM_Sub(L12), UNWRAP_ITEM_Sub(L13), UNWRAP_ITEM_Sub(L14), UNWRAP_ITEM_Sub(L15) }
+#define LIST_Sub_14(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8), UNWRAP_ITEM_Sub(L9), UNWRAP_ITEM_Sub(L10), UNWRAP_ITEM_Sub(L11), UNWRAP_ITEM_Sub(L12), UNWRAP_ITEM_Sub(L13), UNWRAP_ITEM_Sub(L14) }
+#define LIST_Sub_13(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8), UNWRAP_ITEM_Sub(L9), UNWRAP_ITEM_Sub(L10), UNWRAP_ITEM_Sub(L11), UNWRAP_ITEM_Sub(L12), UNWRAP_ITEM_Sub(L13) }
+#define LIST_Sub_12(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8), UNWRAP_ITEM_Sub(L9), UNWRAP_ITEM_Sub(L10), UNWRAP_ITEM_Sub(L11), UNWRAP_ITEM_Sub(L12) }
+#define LIST_Sub_11(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8), UNWRAP_ITEM_Sub(L9), UNWRAP_ITEM_Sub(L10), UNWRAP_ITEM_Sub(L11) }
+#define LIST_Sub_10(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8), UNWRAP_ITEM_Sub(L9), UNWRAP_ITEM_Sub(L10) }
+#define LIST_Sub_9(L1, L2, L3, L4, L5, L6, L7, L8, L9) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8), UNWRAP_ITEM_Sub(L9) }
+#define LIST_Sub_8(L1, L2, L3, L4, L5, L6, L7, L8) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7), UNWRAP_ITEM_Sub(L8) }
+#define LIST_Sub_7(L1, L2, L3, L4, L5, L6, L7) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6), UNWRAP_ITEM_Sub(L7) }
+#define LIST_Sub_6(L1, L2, L3, L4, L5, L6) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5), UNWRAP_ITEM_Sub(L6) }
+#define LIST_Sub_5(L1, L2, L3, L4, L5) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4), UNWRAP_ITEM_Sub(L5) }
+#define LIST_Sub_4(L1, L2, L3, L4) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3), UNWRAP_ITEM_Sub(L4) }
+#define LIST_Sub_3(L1, L2, L3) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2), UNWRAP_ITEM_Sub(L3) }
+#define LIST_Sub_2(L1, L2) { UNWRAP_ITEM_Sub(L1), UNWRAP_ITEM_Sub(L2) }
+#define LIST_Sub_1(L1) { UNWRAP_ITEM_Sub(L1) }
+#define UNWRAP_Sub_2(...) GET_MACRO(__VA_ARGS__, LIST_Sub_16, LIST_Sub_15, LIST_Sub_14, LIST_Sub_13, LIST_Sub_12, LIST_Sub_11, LIST_Sub_10, LIST_Sub_9, LIST_Sub_8, LIST_Sub_7, LIST_Sub_6, LIST_Sub_5, LIST_Sub_4, LIST_Sub_3, LIST_Sub_2, LIST_Sub_1)(__VA_ARGS__)
+#define Submodels(L) SM_(UNWRAP_Sub_2 L)
+
 } }
 
 #endif

+ 30 - 9
src/artis/kernel/Externals.hpp

@@ -23,6 +23,7 @@
 #ifndef __ARTIS_KERNEL_EXTERNALS_HPP
 #define __ARTIS_KERNEL_EXTERNALS_HPP
 
+#include <artis/kernel/Macro.hpp>
 #include <artis/kernel/State.hpp>
 #include <vector>
 
@@ -31,6 +32,18 @@ namespace artis { namespace kernel {
 template < typename T, typename U >
 class Externals
 {
+    template < typename V >
+    struct element
+    {
+        unsigned int index;
+        const std::string name;
+        V T::* var;
+
+        element(unsigned int index, const std::string& name, V T::* var) :
+            index(index), name(name), var(var)
+        { }
+    };
+
 public:
     Externals() : updated(false)
     { }
@@ -53,26 +66,28 @@ public:
     }
 
     template < typename V >
-    void E(std::initializer_list < std::pair < unsigned int,
-           V T::* > > list)
+    void E_(std::initializer_list < element < V > > list)
     {
-        for (typename std::initializer_list < std::pair < unsigned int,
-                 V T::* > >::iterator it = list.begin(); it != list.end();
-             ++it) {
-            if (externals.size() <= it->first) {
-                externals.resize(it->first + 1);
+        for (typename std::initializer_list < element < V > >::iterator it =
+                 list.begin(); it != list.end(); ++it) {
+            if (externals.size() <= it->index) {
+                externals.resize(it->index + 1, std::make_pair(-1, Any()));
+                external_names.resize(it->index + 1, std::string());
             }
-            externals[it->first] = std::make_pair(-1, it->second);
+            externals[it->index] = std::make_pair(-1, it->var);
+            external_names[it->index] = it->name;
         }
     }
 
     template < typename V >
-    void external(unsigned int index, V T::* var)
+    void external_(unsigned int index, const std::string& name, V T::* var)
     {
         if (externals.size() <= index) {
             externals.resize(index + 1, std::make_pair(-1, Any()));
+            external_names.resize(index + 1, std::string());
         }
         externals[index] = std::make_pair(-1, var);
+        external_names[index] = name;
     }
 
     bool is_ready(typename U::type t, unsigned int index) const
@@ -103,8 +118,14 @@ public:
 protected:
     bool updated;
     std::vector < std::pair < typename U::type, Any > > externals;
+    std::vector < std::string > external_names;
 };
 
+#define External(index, var)                                    \
+        external_(index, std::string(ESCAPEQUOTE(index)), var)
+
+#define Externals(V,L) E_< V >(UNWRAP2 L)
+
 } } // namespace artis kernel
 
 #endif

+ 33 - 9
src/artis/kernel/Internals.hpp

@@ -23,6 +23,7 @@
 #ifndef __ARTIS_KERNEL_INTERNALS_HPP
 #define __ARTIS_KERNEL_INTERNALS_HPP
 
+#include <artis/kernel/Macro.hpp>
 #include <artis/kernel/State.hpp>
 #include <artis/kernel/Value.hpp>
 
@@ -33,6 +34,18 @@ namespace artis { namespace kernel {
 template < typename T, typename U >
 class Internals
 {
+    template < typename V >
+    struct element
+    {
+        unsigned int index;
+        const std::string name;
+        V T::* var;
+
+        element(unsigned int index, const std::string& name, V T::* var) :
+            index(index), name(name), var(var)
+        { }
+    };
+
 public:
     Internals()
     { }
@@ -44,28 +57,33 @@ public:
     { return internals.at(index); }
 
     template < typename V >
-    void I(std::initializer_list < std::pair < unsigned int,
-           V T::* > > list)
+    void I_(std::initializer_list < element < V > > list)
     {
-        for (typename std::initializer_list < std::pair < unsigned int,
-                 V T::* > >::iterator it = list.begin(); it != list.end();
-             ++it) {
-            if (internals.size() <= it->first) {
-                internals.resize(it->first + 1);
+        for (typename std::initializer_list <element < V > >::iterator it =
+                 list.begin(); it != list.end(); ++it) {
+            if (internals.size() <= it->index) {
+                internals.resize(it->index + 1);
+                internal_names.resize(it->index + 1, std::string());
             }
-            internals[it->first] = it->second;
+            internals[it->index] = it->var;
+            internal_names[it->index] = it->name;
         }
     }
 
     template < typename V >
-    void internal(unsigned int index, V T::* var)
+    void internal_(unsigned int index, const std::string& name, V T::* var)
     {
         if (internals.size() <= index) {
             internals.resize(index + 1, Any());
+            internal_names.resize(index + 1, std::string());
         }
         internals[index] = Any(var);
+        internal_names[index] = name;
     }
 
+    const std::string& name(unsigned int index) const
+    { return internal_names.at(index); }
+
     virtual void restore(const State < U >& /* state */)
     {
         // unsigned int index = 0;
@@ -117,8 +135,14 @@ public:
 
 private:
     std::vector < Any > internals;
+    std::vector < std::string > internal_names;
 };
 
+#define Internal(index, var)                                    \
+        internal_(index, std::string(ESCAPEQUOTE(index)), var)
+
+#define Internals(V,L) I_< V >(UNWRAP2 L)
+
 } } // namespace artis kernel
 
 #endif

+ 52 - 0
src/artis/kernel/Macro.hpp

@@ -0,0 +1,52 @@
+/**
+ * @file artis/kernel/Macro.hpp
+ * @author See the AUTHORS file
+ */
+
+/*
+ * Copyright (C) 2012-2017 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_MACRO_HPP
+#define __ARTIS_KERNEL_MACRO_HPP
+
+#define DOUBLEESCAPE(a) #a
+#define ESCAPEQUOTE(a) DOUBLEESCAPE(a)
+
+#define ITEM(index, var) { index,                                       \
+                std::string(ESCAPEQUOTE(index)),                        \
+                var }
+#define UNWRAP_ITEM(...) ITEM __VA_ARGS__
+#define LIST_16(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15, L16) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12), UNWRAP_ITEM(L13), UNWRAP_ITEM(L14), UNWRAP_ITEM(L15), UNWRAP_ITEM(L16) }
+#define LIST_15(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14, L15) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12), UNWRAP_ITEM(L13), UNWRAP_ITEM(L14), UNWRAP_ITEM(L15) }
+#define LIST_14(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13, L14) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12), UNWRAP_ITEM(L13), UNWRAP_ITEM(L14) }
+#define LIST_13(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12, L13) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12), UNWRAP_ITEM(L13) }
+#define LIST_12(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11, L12) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11), UNWRAP_ITEM(L12) }
+#define LIST_11(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10), UNWRAP_ITEM(L11) }
+#define LIST_10(L1, L2, L3, L4, L5, L6, L7, L8, L9, L10) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9), UNWRAP_ITEM(L10) }
+#define LIST_9(L1, L2, L3, L4, L5, L6, L7, L8, L9) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8), UNWRAP_ITEM(L9) }
+#define LIST_8(L1, L2, L3, L4, L5, L6, L7, L8) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7), UNWRAP_ITEM(L8) }
+#define LIST_7(L1, L2, L3, L4, L5, L6, L7) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6), UNWRAP_ITEM(L7) }
+#define LIST_6(L1, L2, L3, L4, L5, L6) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5), UNWRAP_ITEM(L6) }
+#define LIST_5(L1, L2, L3, L4, L5) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4), UNWRAP_ITEM(L5) }
+#define LIST_4(L1, L2, L3, L4) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3), UNWRAP_ITEM(L4) }
+#define LIST_3(L1, L2, L3) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2), UNWRAP_ITEM(L3) }
+#define LIST_2(L1, L2) { UNWRAP_ITEM(L1), UNWRAP_ITEM(L2) }
+#define LIST_1(L1) { UNWRAP_ITEM(L1) }
+#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, NAME, ...) NAME
+#define UNWRAP2(...) GET_MACRO(__VA_ARGS__, LIST_16, LIST_15, LIST_14, LIST_13, LIST_12, LIST_11, LIST_10, LIST_9, LIST_8, LIST_7, LIST_6, LIST_5, LIST_4, LIST_3, LIST_2, LIST_1)(__VA_ARGS__)
+
+#endif

+ 30 - 10
src/artis/kernel/States.hpp

@@ -33,6 +33,18 @@ namespace artis { namespace kernel {
 template < typename T, typename U >
 class States
 {
+    template < typename V >
+    struct element
+    {
+        unsigned int index;
+        const std::string name;
+        V T::* var;
+
+        element(unsigned int index, const std::string& name, V T::* var) :
+            index(index), name(name), var(var)
+        { }
+    };
+
 public:
     States()
     { }
@@ -44,16 +56,16 @@ public:
     { return states.at(index); }
 
     template < typename V >
-    void S(std::initializer_list < std::pair < unsigned int,
-           V T::* > > list)
+    void S_(std::initializer_list < element < V > > list)
     {
-        for (typename std::initializer_list < std::pair < unsigned int,
-                 V T::* > >::iterator it = list.begin(); it != list.end();
-             ++it) {
-            if (states.size() <= it->first) {
-                states.resize(it->first + 1);
+        for (typename std::initializer_list < element < V > >::iterator it =
+                 list.begin(); it != list.end(); ++it) {
+            if (states.size() <= it->index) {
+                states.resize(it->index + 1, Any());
+                state_names.resize(it->index + 1, std::string());
             }
-            states[it->first] = it->second;
+            states[it->index] = it->var;
+            state_names[it->index] = it->name;
         }
     }
 
@@ -104,18 +116,26 @@ public:
     }
 
     template < typename V >
-    void state(unsigned int index, V T::* var)
+    void state_(unsigned int index, const std::string& name, V T::* var)
     {
         if (states.size() <= index) {
-            states.resize(index + 1);
+            states.resize(index + 1, Any());
+            state_names.resize(index + 1, std::string());
         }
         states[index] = Any(var);
+        state_names[index] = name;
     }
 
 private:
     std::vector < Any > states;
+    std::vector < std::string > state_names;
 };
 
+#define State(index, var)                                    \
+        state_(index, std::string(ESCAPEQUOTE(index)), var)
+
+#define States(V,L) S_< V >(UNWRAP2 L)
+
 } }
 
 #endif

+ 21 - 13
src/test/models.hpp

@@ -58,9 +58,9 @@ public:
 
     AModel()
     {
-        internal(IX, &AModel::_ix);
-        internal(BX, &AModel::_bx);
-        internal(DX, &AModel::_dx);
+        Internal(IX, &AModel::_ix);
+        Internal(BX, &AModel::_bx);
+        Internal(DX, &AModel::_dx);
     }
 
     virtual ~AModel()
@@ -94,24 +94,24 @@ class BModel : public AtomicModel < BModel >
 {
 public:
     enum externals { IX, BX, DX };
-    enum internals { IY, BY, DY };
+    enum internals { IY, BY, DY, IZ };
     enum states { N };
 
     BModel()
     {
         // external(IX, &BModel::_ix);
-        E < int >({ { IX, &BModel::_ix } });
+        Externals(int, (( IX, &BModel::_ix )));
 
-        external(BX, &BModel::_bx);
-        external(DX, &BModel::_dx);
+        External(BX, &BModel::_bx);
+        External(DX, &BModel::_dx);
 
         // internal(IY, &BModel::_iy);
-        I < int >({ { IY, &BModel::_iy } });
+        Internals(int, ( ( IY, &BModel::_iy ), ( IZ, &BModel::_iz ) ) );
 
-        internal(BY, &BModel::_by);
-        internal(DY, &BModel::_dy);
+        Internal(BY, &BModel::_by);
+        Internal(DY, &BModel::_dy);
 
-        S < int >({ { N, &BModel::_n } });
+        States(int, ((N, &BModel::_n)));
     }
 
     virtual ~BModel()
@@ -134,6 +134,7 @@ public:
         _iy = 0;
         _by = false;
         _dy = 0.;
+        _iz = 0;
         _n = 0;
     }
 
@@ -147,6 +148,7 @@ private:
     int _iy;
     bool _by;
     double _dy;
+    int _iz;
 
     // states
     int _n;
@@ -156,15 +158,21 @@ class RootModel : public CoupledModel < RootModel >
 {
 public:
     enum submodels { A, B };
+    enum internals { IY, BY, DY, IZ };
     enum states { N };
 
     RootModel() : _a(new AModel), _b(new BModel)
     {
         // submodels
-        S({ { A, _a.get() }, { B, _b.get() } });
+        Submodels(((A, _a.get()), (B, _b.get())));
+
+        // internals
+        InternalsS(((IY, _b.get(), BModel::IY), (IZ, _b.get(), BModel::IZ)));
+        InternalS(BY, _b.get(), BModel::BY);
 
         // states
-        S < int >({ { N, &RootModel::_n } });
+        States(int, ((N, &RootModel::_n)));
+        // State(N, &RootModel::_n);
     }
 
     virtual ~RootModel()