15 typedef Real t_moa_real;
16 typedef Vector<2, t_moa_real> t_moa_v2;
17 typedef Vector<3, t_moa_real> t_moa_v3;
18 typedef Vector<4, t_moa_real> t_moa_v4;
19 typedef Matrix<3,3,t_moa_real> t_moa_matrix;
20 typedef Matrix<3,4,t_moa_real> t_moa_xform;
23 class RecordDictionary :
public std::map<String, Record>
26 RecordDictionary(
void)
29 RecordDictionary(sp<RecordGroup> rg_dataset)
33 void build(sp<RecordGroup> rg_dataset)
35 asNamed.bind(rg_dataset->scope());
38 m_as.bind(rg_dataset->scope());
40 std::vector<Record> records;
41 asNamed.filter(records,rg_dataset);
42 for(
unsigned int i = 0; i < records.size(); i++)
44 if(m_as.check(records[i]))
46 if(this->find(asNamed.name(records[i])) != this->end())
48 fe_fprintf(stderr,
"DUPLICATE [%s]\n",
49 asNamed.name(records[i]).c_str());
51 (*this)[asNamed.name(records[i])] = records[i];
56 AS &as(
void) {
return m_as; }
63 class RecordDictionaryByAccessor :
public std::map<String, Record>
66 RecordDictionaryByAccessor(
void)
69 RecordDictionaryByAccessor(sp<RecordGroup> rg_dataset,
70 Accessor<T> &a_accessor)
72 load(rg_dataset, a_accessor);
74 void load(sp<RecordGroup> rg_dataset,
75 Accessor<T> &a_accessor)
77 asNamed.bind(rg_dataset->scope());
79 sp<TypeMaster> spTM = rg_dataset->scope()->typeMaster();
81 spTM->lookupType(TypeInfo(getTypeId<T>()));
83 rg_dataset->scope()->attribute(a_accessor.index())->type())
85 fe_fprintf(stderr,
"accessor type mismatch\n");
89 std::vector<Record> records;
90 asNamed.filter(records,rg_dataset);
91 for(
unsigned int i = 0; i < records.size(); i++)
93 if(a_accessor.check(records[i]))
95 if(this->find(asNamed.name(records[i])) != this->end())
97 fe_fprintf(stderr,
"DUPLICATE [%s]\n",
98 asNamed.name(records[i]).c_str());
101 (*this)[asNamed.name(records[i])] = records[i];
111 template <
typename A,
typename B>
112 void enforce(sp<RecordGroup> a_dataset)
115 asA.bind(a_dataset->scope());
117 asB.bind(a_dataset->scope());
118 asA.enforceHaving(asB);
122 typedef std::atomic<t_moa_real> t_atomic_real;
125 class FE_DL_EXPORT InfoAtomicReal :
public BaseType::Info
128 virtual IWORD output(std::ostream &ostrm,
void *instance, t_serialMode mode)
130 t_moa_real moa_real = *(t_atomic_real *)instance;
133 ostrm.write((
char *)&moa_real,
sizeof(t_moa_real));
134 return sizeof(t_moa_real);
143 virtual void input(std::istream &istrm,
void *instance, t_serialMode mode)
145 t_moa_real moa_real=0.0f;
148 istrm.read((
char *)&moa_real,
sizeof(t_moa_real));
154 *(t_atomic_real *)instance = moa_real;
157 virtual String print(
void *instance)
159 t_moa_real moa_real= *(t_moa_real *)instance;
161 string.sPrintf(
"%.6G",moa_real);
165 virtual void construct(
void *instance)
167 *(t_atomic_real *)instance=0.0;
170 virtual IWORD iosize(
void)
172 return sizeof(t_atomic_real);
182 t_accum_v3(
void) { clear(); }
183 ~t_accum_v3(
void) { }
187 m_data = t_moa_v3(0.0,0.0,0.0);
190 void add(
const t_moa_v3 &a_add)
193 m_data = m_data + a_add;
201 a_other.m_mutex.lock();
202 rv = (m_data == a_other.m_data);
203 a_other.m_mutex.unlock();
211 rv = (m_data == a_other.m_data);
215 void read(t_moa_v3 &a_v3)
223 RecursiveMutex m_mutex;
227 class InfoVectorAccum :
public BaseType::Info
229 virtual String print(
void *instance)
231 const t_accum_v3 *pV = (t_accum_v3 *)instance;
234 string.catf(
"%.6G%s",(*pV).m_data[n],(n==3-1)?
"":
" ");
238 virtual IWORD output(std::ostream &ostrm,
void *instance, t_serialMode mode)
245 t_accum_v3 *pV = (t_accum_v3 *)instance;
246 for(
int i = 0; i < 3; i++)
248 t_moa_real t=(*pV).m_data[i];
249 if(i && mode == e_ascii)
253 n += helpF.output(ostrm, (
void *)&t, mode);
259 return (mode == e_ascii)? c_ascii: n;
261 virtual void input(std::istream &istrm,
void *instance, t_serialMode mode)
263 t_accum_v3 *pV = (t_accum_v3 *)instance;
264 for(
int i = 0; i < 3; i++)
267 helpF.input(istrm, (
void *)&t, mode);
268 setAt(pV->m_data,i,t);
271 virtual IWORD iosize(
void) {
return sizeof(t_accum_v3); }
272 virtual FE_UWORD alignment(
void)
275 return (3*
sizeof(t_moa_real)==FE_MEM_ALIGNMENT)?
281 virtual bool getConstruct(
void) {
return true; }
282 virtual void construct(
void *instance)
283 {
new(instance)t_accum_v3; }
284 virtual void destruct(
void *instance)
285 { ((t_accum_v3 *)instance)->~t_accum_v3();}
294 typedef std::function<void(const int &)> t_note_perform_tmp;
297 class InfoNotePerform :
public BaseType::Info
299 virtual String print(
void *instance)
304 virtual IWORD output(std::ostream &ostrm,
void *instance, t_serialMode mode)
306 if(mode == e_ascii) {
return c_noascii; }
309 virtual void input(std::istream &istrm,
void *instance, t_serialMode mode)
312 virtual IWORD iosize(
void) {
return c_implicit; }
313 virtual bool getConstruct(
void) {
return true; }
314 virtual void construct(
void *instance)
315 {
new(instance)t_note_perform_tmp; }
316 virtual void destruct(
void *instance)
317 { ((t_note_perform_tmp *)instance)->~t_note_perform_tmp();}
322 Record recordFind(sp<RecordGroup> rg_dataset,
323 const String &a_name)
325 RecordDictionary<T> dictionary(rg_dataset);
326 return dictionary[a_name];
329 template<
typename AS>
330 Record createSignal(sp<RecordGroup> a_rg_dataset,
331 const String &a_name)
334 asAS.bind(a_rg_dataset->scope());
335 sp<Layout> l_new = a_rg_dataset->scope()->declare(a_name);
336 asAS.populate(l_new);
337 Record r_new = a_rg_dataset->scope()->createRecord(l_new);
342 inline bool attachAccessorSet(AccessorSet &a_as,
343 sp<RecordGroup> a_rg_dataset,
const String &a_name)
346 std::vector<Record> records;
347 asNamed.filter(records,a_rg_dataset);
348 for(
unsigned int i = 0; i < records.size(); i++)
350 if(asNamed.name(records[i]) == a_name)
352 if(a_as.check(records[i]))
354 a_as.attach(records[i]);
363 inline void split(std::vector<String> &a_tokens, String a_input,
366 String buffer=a_input.c_str();
368 while(!(token=buffer.parse(
"",a_delim)).empty())
370 a_tokens.push_back(token);
374 inline void splitAll(std::vector<String> &a_tokens, String a_input,
377 String buffer=a_input.c_str();
379 while(!(token=buffer.parse(
"",a_delim,TRUE)).empty())
381 a_tokens.push_back(token);
385 inline void split(std::list<String> &a_tokens, String a_input,
388 String buffer=a_input.c_str();
390 while(!(token=buffer.parse(
"",a_delim)).empty())
392 a_tokens.push_back(token);
397 inline void overlay(Record r_dst, Record r_src)
399 const sp<Scope> &spScope = r_src.layout()->scope();
401 t_bitset a_bitset = r_src.layout()->bitset() &
402 r_dst.layout()->bitset();
403 for(
unsigned int i_a = 0; i_a < a_bitset.size(); i_a++)
406 spScope->attribute(i_a)->isCloneable())
412 void *dst = r_dst.rawAttribute(i_a);
413 void *src = r_src.rawAttribute(i_a);
414 spScope->attribute(i_a)->type()->assign(dst, src);
429 if(!a_rg_data.isValid()) {
return; }
430 if(!a_rg_overlay.isValid()) {
return; }
433 asNamed.bind(a_rg_data->scope());
436 std::map< String, Record > named_dataset;
438 i_rg != a_rg_data->end(); i_rg++)
441 if(asNamed.check(spRA))
443 for(
int i = 0; i < spRA->length(); i++)
445 Record r_named = spRA->getRecord(i);
446 named_dataset[asNamed.
name(r_named)] = r_named;
453 i_rg_overlay != a_rg_overlay->end(); i_rg_overlay++)
461 if(asNamed.check(spRAoverlay))
463 for(
int i = 0; i < spRAoverlay->length(); i++)
465 Record record=spRAoverlay->getRecord(i);
467 std::map< String, Record >::iterator i_named =
468 named_dataset.find(asNamed.
name(record));
471 if(i_named != named_dataset.end())
476 Record r_overlay = spRAoverlay->getRecord(i);
477 Record r_dataset = i_named->second;
479 overlay(r_dataset, r_overlay);
484 spRAdataset->addCovert(record);
492 for(
int i = 0; i < spRAoverlay->length(); i++)
494 Record record=spRAoverlay->getRecord(i);
495 spRAdataset->addCovert(record);
503 typedef std::vector<Record> t_r_vector;
514 m_rg_dataset = a_rg_dataset;
517 template<
typename AS>
518 void addX(
const String &a_key)
521 spAS->bind(m_rg_dataset->scope());
522 m_accessorSets[a_key] = spAS;
531 virtual void process(
const t_r_vector &a_in, t_r_vector &a_out) = 0;
538 virtual ~Filter(
void) {}
540 virtual bool filter(
const String &a_arg,
541 const t_r_vector &a_in, t_r_vector &a_out) = 0;
544 class AccessorSetOp :
545 virtual public Op,
public CastableAs<AccessorSetOp>
549 virtual ~AccessorSetOp(
void);
551 virtual void process(
const t_r_vector &a_in, t_r_vector &a_out);
555 t_r_vector m_r_vector;
560 template<
typename AS>
561 void add(
const String &a_key)
565 spASOP->compile(m_rg_dataset);
566 m_op_map[a_key] = spASOP;
569 class BondOp :
virtual public Op,
public CastableAs<BondOp>
573 virtual ~BondOp(
void);
575 virtual void process(
const t_r_vector &a_in, t_r_vector &a_out);
581 t_r_vector m_r_vector;
587 class RecordGroupOp :
588 virtual public Op,
public CastableAs<RecordGroupOp>
592 virtual ~RecordGroupOp(
void);
594 virtual void process(
const t_r_vector &a_in, t_r_vector &a_out);
598 t_r_vector m_r_vector;
601 void addRecordGroup(
const String &a_key,
605 virtual public Filter,
public CastableAs<NameFilter>
609 virtual ~NameFilter(
void);
611 virtual bool filter(
const String &a_arg,
612 const t_r_vector &a_in, t_r_vector &a_out);
618 virtual public Filter,
public CastableAs<IndexFilter>
622 virtual ~IndexFilter(
void);
624 virtual bool filter(
const String &a_arg,
625 const t_r_vector &a_in, t_r_vector &a_out);
630 m_op_vector.push_back(a_filter);
631 a_filter->compile(m_rg_dataset);
634 void locate(t_r_vector &a_records,
const String &a_address);
636 void baseAddress(
const String &a_address,
String &a_base,
639 static bool arrayIndex(
const String &a_input,
640 String &a_trimmed,
unsigned int &a_index);
643 T *find(
const String &a_address)
647 baseAddress(a_address, base, attr);
650 locate(records, base);
651 if(records.size() == 0) {
return NULL; }
655 for(
unsigned int i = 0; i < records.size(); i++)
657 if(accessor.check(records[i]))
659 return &(accessor(records[i]));
666 typedef std::map< String, sp<AccessorSet> > t_asets;
667 typedef std::map< String, sp<Op> > t_op_map;
668 typedef std::vector< sp<Filter> > t_op_vector;
670 t_asets m_accessorSets;
672 t_op_vector m_op_vector;
675 class FE_DL_EXPORT CanonicalStd :
public Canonical 678 CanonicalStd(
void) { }
679 virtual ~CanonicalStd(
void) { }
683 class FE_DL_EXPORT RealAccessor
686 RealAccessor(
void) {}
689 bool check(
const Record& r_hasreal)
const;
691 void set(
const Record& r_hasreal, t_moa_real a_v);
692 t_moa_real
get(
const Record& r_hasreal);
702 unsigned int m_index;
707 Cloner cloner(a_rg->scope());
708 return cloner.clone(a_rg);
711 class FE_DL_EXPORT StreamableI
716 virtual void output(std::ostream &a_ostrm) = 0;
717 virtual void input(std::istream &a_istrm) = 0;
722 template <
typename T>
723 class InfoI :
public BaseType::Info
728 m_spRegistry = a_spRegistry;
731 typedef sp<T> t_interface;
733 virtual IWORD output(std::ostream &ostrm,
void *instance, t_serialMode mode)
738 t_interface &spInterface = *(t_interface *)instance;
739 t_streamable spStreamable = spInterface;
740 if(spInterface.isValid() && spStreamable.isValid())
744 ostrm << spInterface->name().c_str();
746 spStreamable->output(ostrm);
751 ostrm <<
"\"invalid interface\"";
754 return (mode == e_ascii)? c_ascii: n;
756 virtual void input(std::istream &istrm,
void *instance, t_serialMode mode)
770 std::vector< std::string > words;
772 while(!buffer.
empty())
774 String word=buffer.parse(
"'");
777 words.push_back(word.
c_str());
781 if(words.size() >= 2)
783 t_interface &spInterface = *(t_interface *)instance;
785 spInterface = m_spRegistry->
create(words[0].c_str());
787 t_streamable spStreamable = spInterface;
788 if(spInterface.isValid() && spStreamable.isValid())
790 std::istringstream istrm(words[1]);
791 spStreamable->input(istrm);
795 virtual IWORD iosize(
void) {
return BaseType::Info::c_implicit; }
796 virtual bool getConstruct(
void) {
return true; }
797 virtual void construct(
void *instance)
798 {
new(instance)t_interface; }
799 virtual void destruct(
void *instance)
800 { ((t_interface *)instance)->~t_interface();}
805 void assertInterface(
sp<Master> a_spMaster,
const char *a_name)
808 spT = a_spMaster->typeMaster()->assertType<
sp<T> >(a_name);
809 spT->setInfo(
new InfoI<T>(a_spMaster->registry()));
812 #define AsConstruct(AS) \ 814 AS(Record &r){ if(r.isValid()) { bind(r.layout()->scope()); }} \ 815 AS(sp<Scope> a_spScope){ bind(a_spScope); } 821 AsConstruct(AsDatasetMeta);
822 void initialize(
void)
824 add(dictionary, FE_USE(
"dataset:dictionary"));
830 m_dataset = a_dataset;
831 bind(a_dataset->scope());
833 m_r_first_meta =
Record();
834 std::vector<Record> metas;
835 filter(metas, a_dataset);
836 for(
Record &r_meta : metas)
838 if(!m_r_first_meta.isValid())
840 m_r_first_meta = r_meta;
842 for(std::map<String,String>::iterator i_map =
843 dictionary(r_meta).begin();
844 i_map != dictionary(r_meta).end(); i_map++)
846 m_all_map[i_map->first] = r_meta;
852 std::map<String,Record>::iterator i_map =
853 m_all_map.find(a_key);
855 if(i_map == m_all_map.end())
858 i_map = m_all_map.find(a_key);
859 if(i_map == m_all_map.end())
861 return String(
"__unset__") + a_key;
865 return dictionary(i_map->second)[a_key];
869 std::map<String,Record>::iterator i_map =
870 m_all_map.find(a_key);
871 if(i_map == m_all_map.end())
873 if(!m_r_first_meta.isValid())
875 std::vector<Record> metas;
876 filter(metas, m_dataset);
879 m_r_first_meta = metas[0];
884 m_dataset->scope()->declare(
"AUTOMATIC_META");
887 m_dataset->scope()->createRecord(l_first);
888 m_dataset->add(m_r_first_meta);
891 dictionary(m_r_first_meta)[a_key] = a_value;
892 m_all_map[a_key] = m_r_first_meta;
895 dictionary(m_all_map[a_key])[a_key] = a_value;
899 std::map<String,Record> m_all_map;
910 void initialize(
void)
912 add(dataset, FE_USE(
"dataset:group"));
918 class AsDatasetControl
922 AsConstruct(AsDatasetControl);
923 void initialize(
void)
925 add(active, FE_USE(
"dataset:active"));
934 AsConstruct(AsDatasetMixer);
935 void initialize(
void)
937 add(inputs, FE_USE(
"mixer:inputs"));
942 class AsDatasetManyToMany
946 AsConstruct(AsDatasetManyToMany);
947 void initialize(
void)
949 add(left, FE_USE(
"mixer:left"));
950 add(right, FE_USE(
"mixer:right"));
951 add(active, FE_USE(
"dataset:active"));
962 AsConstruct(AsAspect);
963 void initialize(
void)
965 add(label, FE_USE(
"aspect:label"));
970 class FE_DL_EXPORT Overlayer
974 virtual ~Overlayer(
void) {}
977 void load(
const char *a_str)
980 std::ifstream strm(a_str);
981 spStreamDataset=
new data::AsciiStream(m_rg_baseline->scope());
984 m_rg_baseline->add(rg_file);
988 m_rg_baseline->add(a_rg_file);
991 std::vector< sp<RecordGroup> > &bakedDatasets(
void)
1000 RecordDictionary<AsDataset> &datasets(
void) {
return m_datasets; }
1006 void manyToMany(
void);
1008 void bakeControls(
void);
1011 RecordDictionary<AsDataset> m_datasets;
1013 std::vector< sp<RecordGroup> > m_rgs_baked;
1021 std::ifstream strm(a_str);
1022 spStreamDataset=
new data::AsciiStream(a_spRG->scope());
1025 a_spRG->
add(rg_file);
1028 #define e_unnl (int)(1<<0) 1029 #define e_red (int)(1<<1) 1030 #define e_green (int)(1<<2) 1031 #define e_yellow (int)(1<<3) 1032 #define e_blue (int)(1<<4) 1033 #define e_magenta (int)(1<<5) 1034 #define e_cyan (int)(1<<6) 1035 #define e_white (int)(1<<7) 1037 void dump(
const char *a_msg);
1038 void dump(
int a_flags,
const char *a_msg);
1041 void dump(
const char *a_msg, t_moa_real a_r);
1042 void dump(
int a_flags,
const char *a_msg, t_moa_real a_r);
1043 void dump(
const char *a_msg,
const char *a_txt);
1044 void dump(
int a_flags,
const char *a_msg,
const char *a_txt);
1045 void dump(
const char *a_msg,
const t_moa_v3 &a_v3);
1046 void dump(
int a_flags,
const char *a_msg,
const t_moa_v3 &a_v3);
1047 void dump(
const char *a_msg,
const t_moa_xform &a_xform);
1048 void dump(
int a_flags,
const char *a_msg,
const t_moa_xform &a_xform);
1050 void dump(
const char *a_msg,
Record a_r);
1051 void dump(
int a_flags,
const char *a_msg,
Record a_r);
1061 class FE_DL_EXPORT TypeVector<::fe::ext::t_atomic_real> :
1062 public BaseTypeVector
1069 m_size =
sizeof(::fe::ext::t_atomic_real);
1074 virtual ~TypeVector(
void)
1076 if(m_vector) {
delete [] m_vector; }
1079 virtual void resize(
unsigned int a_size)
1091 else if(a_size > m_count_used)
1093 if(a_size > m_count_alloc)
1095 unsigned int new_alloc = 1;
1096 if(m_count_alloc > 0) { new_alloc = m_count_alloc * 2; }
1097 ::fe::ext::t_atomic_real *from = m_vector;
1098 m_vector = new ::fe::ext::t_atomic_real[new_alloc];
1100 for(
unsigned int i = 0; i < m_count_used; i++)
1102 ::fe::ext::t_moa_real intermediary = from[i];
1103 m_vector[i] = intermediary;
1106 m_count_alloc = new_alloc;
1108 for(
unsigned int i = m_count_used; i < a_size; i++)
1113 m_count_used = a_size;
1116 virtual void *raw_at(
unsigned int a_index)
1118 return (
void *)&m_vector[a_index];
1121 ::fe::ext::t_atomic_real &at(
unsigned int a_index)
1123 return m_vector[a_index];
1127 ::fe::ext::t_atomic_real *m_vector;
1128 unsigned int m_count_alloc;
1129 unsigned int m_count_used;
1136 ::fe::ext::t_moa_real moa_real =
1137 *(
reinterpret_cast<::fe::ext::t_atomic_real *
>(rvalue));
1138 *(
reinterpret_cast<::fe::ext::t_atomic_real *
>(lvalue)) = moa_real;
1153 assert(a_args.size() >= 3);
1156 m_start = a_args[0].real();
1157 m_end = a_args[1].real();
1158 if(a_args[2].c_str()[0] ==
'*')
1160 String n = a_args[2].prechop(
"*");
1166 m_incr = a_args[2].real();
1179 friend class EvalRange;
1186 iterator(
const iterator& it)
1188 m_value = it.m_value;
1191 ::fe::ext::t_moa_real &operator*(
void)
1195 ::fe::ext::t_moa_real *operator->(
void)
1199 iterator operator++()
1205 iterator operator++(
int dummy)
1213 return (m_end == other.m_end);
1217 return (m_end != other.m_end);
1220 void increment(
void)
1222 if(m_pRange->m_mode == 1)
1224 m_value = m_value * m_pRange->m_incr;
1228 m_value = m_value + m_pRange->m_incr;
1231 void check_for_end(
void)
1233 if(m_pRange->m_end >= m_pRange->m_start)
1235 if(m_value > m_pRange->m_end) { m_end =
true; }
1239 if(m_value < m_pRange->m_end) { m_end =
true; }
1243 ::fe::ext::t_moa_real m_value;
1245 EvalRange *m_pRange;
1248 iterator begin(
void)
1252 it.m_value = m_start;
1264 ::fe::ext::t_moa_real operator[] (
int i)
1266 if(i == 0) {
return m_start; }
1267 else if(i == 1) {
return m_end; }
1268 else if(i == 2) {
return m_incr; }
1272 ::fe::ext::t_moa_real m_start;
1273 ::fe::ext::t_moa_real m_end;
1274 ::fe::ext::t_moa_real m_incr;
1287 spStream=
new data::AsciiStream(a_spRG->scope());
1288 std::ofstream asciifile(a_str);
1289 spStream->output(asciifile, a_spRG);
Deep cloning tool.
Definition: Cloner.h:15
Set of accessors.
Definition: AccessorSet.h:18
virtual void add(const Record &record)
Add record to the collection.
Definition: RecordGroup.cc:77
void watcherAdd(const Record &record)
Definition: RecordGroup.cc:59
const FESTRING_I8 * c_str(void) const
Return the contents of the 8-bit buffer cast as signed bytes.
Definition: String.h:352
Associates a name with a RecordGroup.
Definition: old/moa/data.h:905
Heap-based support for classes participating in fe::ptr <>
Definition: Counted.h:35
kernel
Definition: namespace.dox:3
Per-class participation in the Initialized <> mechanism.
Definition: Initialized.h:117
The main data access class for the data system.
Definition: Accessor.h:128
BWORD operator!=(const DualString &s1, const DualString &s2)
Compare two DualString's (reverse logic)
Definition: DualString.h:229
A class to associate functionality with run time types.
Definition: Type.h:571
sp< Component > create(const String &a_pattern, BWORD quiet=FALSE) const
Instantiate a Component of the given named implementation.
Definition: Registry.cc:628
BWORD operator==(const DualString &s1, const DualString &s2)
Compare two DualString's.
Definition: DualString.h:208
Named Records.
Definition: datatoolAS.h:134
BWORD empty(void) const
Returns true if the contents have zero length.
Definition: String.h:667
Automatically reference-counted string container.
Definition: String.h:128
Get a vector of Records using a string "address".
Definition: old/moa/data.h:507
STL style iterator.
Definition: RecordGroup.h:124
Wrapper for std::vector.
Definition: Array.h:21
Reference to an instance of a Layout.
Definition: RecordSB.h:35
Base for all interfacable components.
Definition: Component.h:20
Accessor< String > name
string name
Definition: datatoolAS.h:144
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192