1010
1111#include " Framework/RootConfigParamHelpers.h"
1212#include " Framework/ConfigParamSpec.h"
13+ #include " Framework/StringHelpers.h"
1314#include < TClass.h>
1415#include < TDataMember.h>
1516#include < TDataType.h>
@@ -35,14 +36,14 @@ bool isString(TDataMember const& dm)
3536// a generic looper of data members of a TClass; calling a callback
3637// reused in various functions below
3738void loopOverMembers (TClass* cl, void * obj,
38- std::function<void (const TDataMember*, int , int )>&& callback)
39+ std::function<void (TDataMember*, int , int )>&& callback)
3940{
4041 auto memberlist = cl->GetListOfDataMembers ();
4142 for (int i = 0 ; i < memberlist->GetEntries (); ++i) {
4243 auto dm = (TDataMember*)memberlist->At (i);
4344
4445 auto isValidComplex = [dm]() {
45- return isString (*dm) || dm->IsEnum ();
46+ return isString (*dm) || dm->IsEnum () || dm-> IsSTLContainer () ;
4647 };
4748
4849 // filter out static members for now
@@ -70,6 +71,20 @@ void loopOverMembers(TClass* cl, void* obj,
7071 }
7172}
7273
74+ namespace
75+ {
76+ template <typename T>
77+ std::vector<T> extractVector (boost::property_tree::ptree const & tree)
78+ {
79+ std::vector<T> result (tree.size ());
80+ auto count = 0u ;
81+ for (auto & entry : tree) {
82+ result[count++] = entry.second .get_value <T>();
83+ }
84+ return result;
85+ }
86+ } // namespace
87+
7388// construct name (in dependence on vector or scalar data and index)
7489std::string getName (const TDataMember* dm, int index, int size)
7590{
@@ -83,7 +98,7 @@ std::string getName(const TDataMember* dm, int index, int size)
8398
8499void ptreeToMember (boost::property_tree::ptree const & value,
85100 char const * tname,
86- TDataMember const * dm,
101+ TDataMember* dm,
87102 void * ptr)
88103{
89104 auto dt = dm->GetDataType ();
@@ -150,6 +165,23 @@ void ptreeToMember(boost::property_tree::ptree const& value,
150165 }
151166 }
152167 }
168+ if (dm->IsSTLContainer ()) {
169+ auto type = dm->GetTypeName ();
170+ switch (compile_time_hash (type)) {
171+ case compile_time_hash (" vector<int>" ):
172+ *static_cast <std::vector<int >*>(ptr) = extractVector<int >(value);
173+ return ;
174+ case compile_time_hash (" vector<float>" ):
175+ *static_cast <std::vector<float >*>(ptr) = extractVector<float >(value);
176+ return ;
177+ case compile_time_hash (" vector<double>" ):
178+ *static_cast <std::vector<double >*>(ptr) = extractVector<double >(value);
179+ return ;
180+ case compile_time_hash (" vector<bool>" ):
181+ default :
182+ throw std::runtime_error (" Not and int/float/double/bool vector" );
183+ }
184+ }
153185 // if we get here none of the above worked
154186 if (strcmp (tname, " string" ) == 0 || strcmp (tname, " std::string" )) {
155187 *(std::string*)ptr = value.get_value <std::string>();
@@ -158,7 +190,7 @@ void ptreeToMember(boost::property_tree::ptree const& value,
158190}
159191
160192// Convert a DataMember to a ConfigParamSpec
161- ConfigParamSpec memberToConfigParamSpec (const char * tname, TDataMember const * dm, void * ptr)
193+ ConfigParamSpec memberToConfigParamSpec (const char * tname, TDataMember* dm, void * ptr)
162194{
163195 auto dt = dm->GetDataType ();
164196 if (dt != nullptr ) {
@@ -210,6 +242,22 @@ ConfigParamSpec memberToConfigParamSpec(const char* tname, TDataMember const* dm
210242 }
211243 }
212244 }
245+ if (dm->IsSTLContainer ()) {
246+ auto type = dm->GetTypeName ();
247+ switch (compile_time_hash (type)) {
248+ case compile_time_hash (" vector<int>" ):
249+ return ConfigParamSpec{tname, VariantType::ArrayInt, *static_cast <std::vector<int >*>(ptr), {" No help" }};
250+ case compile_time_hash (" vector<float>" ):
251+ return ConfigParamSpec{tname, VariantType::ArrayFloat, *static_cast <std::vector<float >*>(ptr), {" No help" }};
252+ case compile_time_hash (" vector<double>" ):
253+ return ConfigParamSpec{tname, VariantType::ArrayDouble, *static_cast <std::vector<double >*>(ptr), {" No help" }};
254+ case compile_time_hash (" vector<bool>" ):
255+ throw std::runtime_error (" bool vector not supported yet" );
256+ // return ConfigParamSpec{tname, VariantType::ArrayBool, *static_cast<std::vector<bool>*>(ptr), {"No help"}};
257+ default :
258+ throw std::runtime_error (" Not and int/float/double/bool vector" );
259+ }
260+ }
213261 // if we get here none of the above worked
214262 if (strcmp (tname, " string" ) == 0 || strcmp (tname, " std::string" )) {
215263 return ConfigParamSpec{tname, VariantType::String, *(std::string*)ptr, {" No help" }};
@@ -226,7 +274,7 @@ std::vector<ConfigParamSpec>
226274{
227275 std::vector<ConfigParamSpec> specs;
228276
229- auto toDataMember = [&mainKey, &specs, obj](const TDataMember* dm, int index, int size) {
277+ auto toDataMember = [&mainKey, &specs, obj](TDataMember* dm, int index, int size) {
230278 auto dt = dm->GetDataType ();
231279 auto TS = dt ? dt->Size () : 0 ;
232280 char * ptr = ((char *)obj) + dm->GetOffset () + index * TS;
@@ -243,7 +291,7 @@ std::vector<ConfigParamSpec>
243291// / using the values in the ptree to override, where appropriate.
244292void RootConfigParamHelpers::fillFromPtree (TClass* cl, void * obj, boost::property_tree::ptree const & pt)
245293{
246- auto toDataMember = [obj, &pt](const TDataMember* dm, int index, int size) {
294+ auto toDataMember = [obj, &pt](TDataMember* dm, int index, int size) {
247295 auto dt = dm->GetDataType ();
248296 auto TS = dt ? dt->Size () : 0 ;
249297 char * ptr = ((char *)obj) + dm->GetOffset () + index * TS;
0 commit comments