35 template<
class T>
struct TypeName
37 static std::string name () {
return typeid (T).name();}
40 template<> struct TypeName<X> { \
41 static std::string name () {return #X;}; };
49 template<
class From,
class To>
struct Convert
51 static void convert (
const std::string& , To& ,
const std::string& field)
55 throw std::runtime_error (
"no conversion defined from type " + TypeName<From>::name() +
" to type " + TypeName<To>::name() +
" for field " + field);
66 template<
class To>
struct Convert<
std::
string,To>
68 static void convert (
const std::string& from, To& to,
const std::string& field)
70 std::stringstream
ss (from);
73 if (!(
ss.fail() ||
ss.rdbuf()->in_avail() > 0))
80 throw std::runtime_error (
"unable to convert string '" + from +
"' to type " + TypeName<To>::name() +
" for field " + field);
84 template<
class Type>
struct Convert<
Type,
Type>
86 static void convert (
const Type& from,
Type& to,
const std::string& )
92 template<
class From>
struct Convert<From,
std::
string>
94 static void convert (
const From& from, std::string& to,
const std::string& )
96 std::ostringstream
ss;
102 template<>
struct Convert<bool,
std::
string>
104 static void convert (
const bool& from, std::string& to,
const std::string& )
113 template<>
struct Convert<
std::
string,bool>
115 static void convert (
const std::string& from,
bool& to,
const std::string& field)
117 if (from ==
"true" || from ==
"True" || from ==
"TRUE" || from ==
"1")
122 if (from ==
"false" || from ==
"False" || from ==
"FALSE" || from ==
"0")
129 throw std::runtime_error (
"unable to convert string '" + from +
"' to type bool for field " + field);
133#define DEFAULT_CONVERT(FROM,TO) \
134 template<> struct Convert<FROM,TO> { \
135 static void convert (const FROM& from, TO& to, const std::string& ) { \
144#undef DEFAULT_CONVERT
147 template<
class From,
class To>
bool
148 convertSingle (
const TObject *from, To& to,
const std::string& field)
150 const MetaData<From> *myfrom =
151 dynamic_cast<const MetaData<From>*
>(from);
154 Convert<From,To>::convert (myfrom->value, to, field);
158 template<
class To>
void
159 convert (
const TObject *from, To& to,
const std::string& field)
161 if (convertSingle<std::string> (from, to, field))
return;
162 if (convertSingle<double> (from, to, field))
return;
163 if (convertSingle<int> (from, to, field))
return;
164 if (convertSingle<bool> (from, to, field))
return;
166 throw std::runtime_error (std::format (
"unkown input type {} for field {}",
typeid(*from).name(), field));
174 std::string
trim (
const std::string&
str)
176 size_t endpos =
str.find_last_not_of(
" \t");
177 size_t startpos =
str.find_first_not_of(
" \t");
178 if( std::string::npos == endpos )
return "";
179 if(
str[startpos] ==
'"' ||
str[startpos] ==
'\'') startpos++;
180 if(
str[endpos] ==
'"' ||
str[endpos] ==
'\'') endpos--;
181 return str.substr( startpos, endpos+1-startpos );
197 template<class T> T getT(const std::string& name, T def_val) const;
209 template<class T> static T convertT(const TObject* meta, T defval);
215 std::string
dbg (
const MetaObject& ,
unsigned )
222 void swap (MetaObject&
a, MetaObject& b)
230 testInvariant ()
const
239 : m_dataList (
new TList)
241 m_dataList->SetOwner(
true);
248 MetaObject (
const MetaObject& that)
249 : TCollection (), m_dataList (
new TList)
251 m_dataList->SetOwner(
true);
254 while ((
object = iter.Next()))
256 m_dataList->Add (object->Clone());
274 MetaObject& MetaObject ::
275 operator = (
const MetaObject& that)
278 MetaObject tmp (that);
286 swap (MetaObject& that)
294 remove (
const std::string& name)
299 while ((
object = m_dataList->FindObject (name.c_str())))
300 delete m_dataList->Remove (
object);
306 addReplace (TNamed *meta_swallow)
308 std::unique_ptr<TNamed>
meta (meta_swallow);
312 remove (meta_swallow->GetName());
313 m_dataList->Add (
meta.release());
318 TObject *MetaObject ::
319 get (
const std::string& name)
322 return m_dataList->FindObject (name.c_str());
327 const TObject *MetaObject ::
328 get (
const std::string& name)
const
331 return m_dataList->FindObject (name.c_str());
337 getDouble (
const std::string& name,
double def_val)
const
340 return castDouble (name, def_val, CAST_NOCAST_DEFAULT);
345 std::string MetaObject ::
346 getString (
const std::string& name,
const std::string& def_val)
const
349 return castString (name, def_val, CAST_NOCAST_DEFAULT);
355 castDouble (
const std::string& name,
double def_val,
358 return castT (name, def_val, mode);
363 std::string MetaObject ::
364 castString (
const std::string& name,
const std::string& def_val,
367 return castT(name,def_val, mode);
372 castInteger (
const std::string& name,
int def_val,
375 return castT(name,def_val, mode);
380 castBool (
const std::string& name,
bool def_val,
383 return castT(name,def_val, mode);
388 setDouble (
const std::string& name,
double value)
396 setString (
const std::string& name,
const std::string& value)
403 setInteger (
const std::string& name,
int value)
410 setBool (
const std::string& name,
bool value)
417 fetch (
const MetaObject& source)
421 TIter iter (&source);
423 while ((
object = iter.Next()))
425 TNamed *
const named =
dynamic_cast<TNamed*
>(object);
428 m_dataList->Add (object->Clone());
429 }
else if (strncmp (named->GetName(),
"nc_", 3) != 0)
431 addReplace (
dynamic_cast<TNamed*
>(named->Clone ()));
439 fetchDefaults (
const MetaObject& source)
443 TIter iter (&source);
445 while ((
object = iter.Next()))
447 if (
get (object->GetName ()) == 0)
448 m_dataList->Add (object->Clone());
455 Add (TObject *meta_swallow)
457 std::unique_ptr<TObject>
meta (meta_swallow);
460 m_dataList->Add (
meta.release());
465 Add (TObject *meta_swallow, Option_t*)
467 this->Add (meta_swallow);
473 Clear (Option_t *option)
476 m_dataList->Clear (option);
482 Delete (Option_t *option)
485 m_dataList->Delete (option);
490 TObject **MetaObject ::
491 GetObjectRef (
const TObject *
const meta)
const
496 TObject **
const result = m_dataList->GetObjectRef (
meta);
505 TIterator *MetaObject ::
506 MakeIterator (Bool_t dir)
const
510 std::unique_ptr<TIterator> result (m_dataList->MakeIterator (dir));
513 return result.release();
518 TObject *MetaObject ::
519 Remove (TObject *
meta)
523 return m_dataList->Remove (
meta);
529 Streamer (TBuffer& b)
534 TObject::Streamer (b);
535 m_dataList->Clear ();
536 m_dataList->Streamer (b);
540 TObject::Streamer (b);
541 m_dataList->Streamer (b);
546 template<
class T> T MetaObject ::
547 castT (
const std::string& name, T def_val, CastMode mode)
const
550 const TObject*
meta =
get (name);
553 const MetaData<T> *
const retval =
dynamic_cast<const MetaData<T>*
>(
meta);
555 return retval->value;
558 case CAST_ERROR_THROW:
561 convert (
meta, result, name);
564 case CAST_ERROR_DEFAULT:
567 convert (
meta, result,
"");
570 case CAST_NOCAST_THROW:
571 throw std::runtime_error (
"invalid input value for " + name);
572 case CAST_NOCAST_DEFAULT:
581 fetchFromString(
const std::string& source){
584 while(pos<source.size() && pos > 0){
585 size_t split = source.find(
"=",oldpos);
586 pos = source.find(
",",
split);
588 std::string key =
trim(source.substr(oldpos,
split-oldpos));
590 this->setString(key,value);
592 throw std::runtime_error (
"unable to parse string '" + source +
"'");
598 std::string MetaObject ::
600 std::stringstream
ss;
601 TIterator* itr = this->MakeIterator();
603 while( (obj = itr->Next()) ){
604 Meta* m =
dynamic_cast<Meta*
>(obj);
606 if(!
ss.str().empty())
ss <<
", ";
607 ss << m->GetName() <<
"=";
608 MetaData<std::string>* s =
dynamic_cast<MetaData<std::string>*
>(m);
610 ss <<
"\"" << s->value <<
"\"";
612 std::string mystring;
613 convert<std::string> (m, mystring, m->GetName());
622 return this->m_dataList->GetEntries();