Free Electron
old/moa/data.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __moa_data_h__
8 #define __moa_data_h__
9 
10 namespace fe
11 {
12 namespace ext
13 {
14 
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;
21 
22 template<class AS>
23 class RecordDictionary : public std::map<String, Record>
24 {
25  public:
26  RecordDictionary(void)
27  {
28  }
29  RecordDictionary(sp<RecordGroup> rg_dataset)
30  {
31  build(rg_dataset);
32  }
33  void build(sp<RecordGroup> rg_dataset)
34  {
35  asNamed.bind(rg_dataset->scope());
36 
37  //AS as;
38  m_as.bind(rg_dataset->scope());
39 
40  std::vector<Record> records;
41  asNamed.filter(records,rg_dataset);
42  for(unsigned int i = 0; i < records.size(); i++)
43  {
44  if(m_as.check(records[i]))
45  {
46  if(this->find(asNamed.name(records[i])) != this->end())
47  {
48  fe_fprintf(stderr, "DUPLICATE [%s]\n",
49  asNamed.name(records[i]).c_str());
50  }
51  (*this)[asNamed.name(records[i])] = records[i];
52  }
53  }
54  }
55 
56  AS &as(void) { return m_as; }
57  private:
58  AsNamed asNamed;
59  AS m_as;
60 };
61 
62 template<typename T>
63 class RecordDictionaryByAccessor : public std::map<String, Record>
64 {
65  public:
66  RecordDictionaryByAccessor(void)
67  {
68  }
69  RecordDictionaryByAccessor(sp<RecordGroup> rg_dataset,
70  Accessor<T> &a_accessor)
71  {
72  load(rg_dataset, a_accessor);
73  }
74  void load(sp<RecordGroup> rg_dataset,
75  Accessor<T> &a_accessor)
76  {
77  asNamed.bind(rg_dataset->scope());
78 
79  sp<TypeMaster> spTM = rg_dataset->scope()->typeMaster();
80  sp<BaseType> spType =
81  spTM->lookupType(TypeInfo(getTypeId<T>()));
82  if(spType !=
83  rg_dataset->scope()->attribute(a_accessor.index())->type())
84  {
85  fe_fprintf(stderr, "accessor type mismatch\n");
86  }
87  else
88  {
89  std::vector<Record> records;
90  asNamed.filter(records,rg_dataset);
91  for(unsigned int i = 0; i < records.size(); i++)
92  {
93  if(a_accessor.check(records[i]))
94  {
95  if(this->find(asNamed.name(records[i])) != this->end())
96  {
97  fe_fprintf(stderr, "DUPLICATE [%s]\n",
98  asNamed.name(records[i]).c_str());
99  assert(false);
100  }
101  (*this)[asNamed.name(records[i])] = records[i];
102  }
103  }
104  }
105  }
106  private:
107  AsNamed asNamed;
108 };
109 
110 
111 template <typename A, typename B>
112 void enforce(sp<RecordGroup> a_dataset)
113 {
114  A asA;
115  asA.bind(a_dataset->scope());
116  B asB;
117  asB.bind(a_dataset->scope());
118  asA.enforceHaving(asB);
119 }
120 
121 
122 typedef std::atomic<t_moa_real> t_atomic_real;
123 
124 
125 class FE_DL_EXPORT InfoAtomicReal : public BaseType::Info
126 {
127  public:
128 virtual IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode)
129 {
130  t_moa_real moa_real = *(t_atomic_real *)instance;
131  if(mode == e_binary)
132  {
133  ostrm.write((char *)&moa_real, sizeof(t_moa_real));
134  return sizeof(t_moa_real);
135  }
136  else
137  {
138  ostrm << moa_real;
139  return c_ascii;
140  }
141 }
142 
143 virtual void input(std::istream &istrm, void *instance, t_serialMode mode)
144 {
145  t_moa_real moa_real=0.0f;
146  if(mode == e_binary)
147  {
148  istrm.read((char *)&moa_real, sizeof(t_moa_real));
149  }
150  else
151  {
152  istrm >> moa_real;
153  }
154  *(t_atomic_real *)instance = moa_real;
155 }
156 
157 virtual String print(void *instance)
158 {
159  t_moa_real moa_real= *(t_moa_real *)instance;
160  String string;
161  string.sPrintf("%.6G",moa_real);
162  return string;
163 }
164 
165 virtual void construct(void *instance)
166 {
167  *(t_atomic_real *)instance=0.0;
168 }
169 
170 virtual IWORD iosize(void)
171 {
172  return sizeof(t_atomic_real);
173 }
174 
175 
176 };
177 
178 // prevent common bug of assigning when should be accumulating
179 class t_accum_v3
180 {
181  public:
182  t_accum_v3(void) { clear(); }
183  ~t_accum_v3(void) { }
184  void clear(void)
185  {
186  m_mutex.lock();
187  m_data = t_moa_v3(0.0,0.0,0.0);
188  m_mutex.unlock();
189  }
190  void add(const t_moa_v3 &a_add)
191  {
192  m_mutex.lock();
193  m_data = m_data + a_add;
194  m_mutex.unlock();
195  }
196 
197  bool operator == (t_accum_v3 &a_other)
198  {
199  bool rv;
200  m_mutex.lock();
201  a_other.m_mutex.lock();
202  rv = (m_data == a_other.m_data);
203  a_other.m_mutex.unlock();
204  m_mutex.unlock();
205  return rv;
206  }
207  bool operator == (t_moa_v3 &a_other)
208  {
209  bool rv;
210  m_mutex.lock();
211  rv = (m_data == a_other.m_data);
212  m_mutex.unlock();
213  return rv;
214  }
215  void read(t_moa_v3 &a_v3)
216  {
217  m_mutex.lock();
218  a_v3 = m_data;
219  m_mutex.unlock();
220  }
221 
222  t_moa_v3 m_data;
223  RecursiveMutex m_mutex;
224 };
225 
226 
227 class InfoVectorAccum : public BaseType::Info
228 {
229 virtual String print(void *instance)
230  {
231  const t_accum_v3 *pV = (t_accum_v3 *)instance;
232  String string;
233  for(U32 n=0;n<3;n++)
234  string.catf("%.6G%s",(*pV).m_data[n],(n==3-1)? "": " ");
235  return string;
236  }
237 
238 virtual IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode)
239  {
240  if(mode == e_ascii)
241  {
242  ostrm << '"';
243  }
244  IWORD n = 0;
245  t_accum_v3 *pV = (t_accum_v3 *)instance;
246  for(int i = 0; i < 3; i++)
247  {
248  t_moa_real t=(*pV).m_data[i];
249  if(i && mode == e_ascii)
250  {
251  ostrm << ' ';
252  }
253  n += helpF.output(ostrm, (void *)&t, mode);
254  }
255  if(mode == e_ascii)
256  {
257  ostrm << '"';
258  }
259  return (mode == e_ascii)? c_ascii: n;
260  }
261 virtual void input(std::istream &istrm, void *instance, t_serialMode mode)
262  {
263  t_accum_v3 *pV = (t_accum_v3 *)instance;
264  for(int i = 0; i < 3; i++)
265  {
266  t_moa_real t=0.0f;
267  helpF.input(istrm, (void *)&t, mode);
268  setAt(pV->m_data,i,t);
269  }
270  }
271 virtual IWORD iosize(void) { return sizeof(t_accum_v3); }
272 virtual FE_UWORD alignment(void)
273  {
274 #if FE_MEM_ALIGNMENT
275  return (3*sizeof(t_moa_real)==FE_MEM_ALIGNMENT)?
276  FE_MEM_ALIGNMENT: 0;
277 #else
278  return 0;
279 #endif
280  }
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();}
286  private:
287 #if FE_DOUBLE_REAL
288  InfoF64 helpF;
289 #else
290  InfoF32 helpF;
291 #endif
292 };
293 
294 typedef std::function<void(const int &)> t_note_perform_tmp;
295 
296 
297 class InfoNotePerform : public BaseType::Info
298 {
299 virtual String print(void *instance)
300  {
301  return "--";
302  }
303 
304 virtual IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode)
305  {
306  if(mode == e_ascii) { return c_noascii; }
307  return 0;
308  }
309 virtual void input(std::istream &istrm, void *instance, t_serialMode mode)
310  {
311  }
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();}
318  private:
319 };
320 
321 template<typename T>
322 Record recordFind(sp<RecordGroup> rg_dataset,
323  const String &a_name)
324 {
325  RecordDictionary<T> dictionary(rg_dataset);
326  return dictionary[a_name];
327 }
328 
329 template<typename AS>
330 Record createSignal(sp<RecordGroup> a_rg_dataset,
331  const String &a_name)
332 {
333  AS asAS;
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);
338  return r_new;
339 }
340 
341 #if 0
342 inline bool attachAccessorSet(AccessorSet &a_as,
343  sp<RecordGroup> a_rg_dataset, const String &a_name)
344 {
345  AsNamed asNamed;
346  std::vector<Record> records;
347  asNamed.filter(records,a_rg_dataset);
348  for(unsigned int i = 0; i < records.size(); i++)
349  {
350  if(asNamed.name(records[i]) == a_name)
351  {
352  if(a_as.check(records[i]))
353  {
354  a_as.attach(records[i]);
355  return true;
356  }
357  }
358  }
359  return false;
360 }
361 #endif
362 
363 inline void split(std::vector<String> &a_tokens, String a_input,
364  String a_delim)
365 {
366  String buffer=a_input.c_str();
367  String token;
368  while(!(token=buffer.parse("",a_delim)).empty())
369  {
370  a_tokens.push_back(token);
371  }
372 }
373 
374 inline void splitAll(std::vector<String> &a_tokens, String a_input,
375  String a_delim)
376 {
377  String buffer=a_input.c_str();
378  String token;
379  while(!(token=buffer.parse("",a_delim,TRUE)).empty())
380  {
381  a_tokens.push_back(token);
382  }
383 }
384 
385 inline void split(std::list<String> &a_tokens, String a_input,
386  String a_delim)
387 {
388  String buffer=a_input.c_str();
389  String token;
390  while(!(token=buffer.parse("",a_delim)).empty())
391  {
392  a_tokens.push_back(token);
393  }
394 }
395 
396 
397 inline void overlay(Record r_dst, Record r_src)
398 {
399  const sp<Scope> &spScope = r_src.layout()->scope();
400 
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++)
404  {
405  if(a_bitset[i_a] &&
406  spScope->attribute(i_a)->isCloneable())
407  {
408  // make sure :CT and :SN don't hit
409  FEASSERT(i_a != 0);
410  FEASSERT(i_a != 1);
411 
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);
415  }
416  }
417 }
418 
419 
420 
421 /** @brief merge a RecordGroup over another RecordGroup.
422 
423 */
424 inline void overlay(sp<RecordGroup> a_rg_data,
425  const sp<RecordGroup> &a_rg_overlay)
426 {
427 //TODO:X fix this painfully slow A-Z only implementation
428 
429  if(!a_rg_data.isValid()) { return; }
430  if(!a_rg_overlay.isValid()) { return; }
431 
432  AsNamed asNamed;
433  asNamed.bind(a_rg_data->scope());
434 
435  // load all named records from target to a map
436  std::map< String, Record > named_dataset;
437  for(RecordGroup::iterator i_rg = a_rg_data->begin();
438  i_rg != a_rg_data->end(); i_rg++)
439  {
440  sp<RecordArray> spRA = *i_rg;
441  if(asNamed.check(spRA))
442  {
443  for(int i = 0; i < spRA->length(); i++)
444  {
445  Record r_named = spRA->getRecord(i);
446  named_dataset[asNamed.name(r_named)] = r_named;
447  }
448  }
449  }
450 
451  // iterate through records in the overlay
452  for(RecordGroup::iterator i_rg_overlay = a_rg_overlay->begin();
453  i_rg_overlay != a_rg_overlay->end(); i_rg_overlay++)
454  {
455  sp<RecordArray> spRAoverlay = *i_rg_overlay;
456 
457  sp<Layout> spLayout=spRAoverlay->layout();
458  sp<RecordArray> spRAdataset = a_rg_data->getArray(spLayout);
459 
460  // For named records
461  if(asNamed.check(spRAoverlay))
462  {
463  for(int i = 0; i < spRAoverlay->length(); i++)
464  {
465  Record record=spRAoverlay->getRecord(i);
466 
467  std::map< String, Record >::iterator i_named =
468  named_dataset.find(asNamed.name(record));
469 
470  // if both RGs have the same named Record, overlay per attribute
471  if(i_named != named_dataset.end())
472  {
473 
474 
475 
476  Record r_overlay = spRAoverlay->getRecord(i);
477  Record r_dataset = i_named->second;
478 
479  overlay(r_dataset, r_overlay);
480  }
481  // if the target RG doesn't have a match, just add the new one
482  else
483  {
484  spRAdataset->addCovert(record);
485  a_rg_data->watcherAdd(record);
486  }
487  }
488  }
489  // For unnamed Records, just add
490  else
491  {
492  for(int i = 0; i < spRAoverlay->length(); i++)
493  {
494  Record record=spRAoverlay->getRecord(i);
495  spRAdataset->addCovert(record);
496  a_rg_data->watcherAdd(record);
497  }
498  }
499  }
500 }
501 
502 
503 typedef std::vector<Record> t_r_vector;
504 
505 /** @brief Get a vector of Records using a string "address"
506 */
507 class FE_DL_EXPORT Canonical
508 {
509  public:
510  Canonical(void) {}
511 virtual ~Canonical(void);
512 virtual void bind(sp<RecordGroup> a_rg_dataset)
513  {
514  m_rg_dataset = a_rg_dataset;
515  }
516 
517  template<typename AS>
518  void addX(const String &a_key)
519  {
520  sp<AS> spAS(new AS());
521  spAS->bind(m_rg_dataset->scope());
522  m_accessorSets[a_key] = spAS;
523  }
524 
525  class Op : virtual public Counted, public CastableAs<Op>
526  {
527  public:
528  Op(void) {}
529 virtual ~Op(void) {}
530 virtual void compile(sp<RecordGroup> a_rg_dataset) = 0;
531 virtual void process(const t_r_vector &a_in, t_r_vector &a_out) = 0;
532  };
533 
534  class Filter : virtual public Counted, public CastableAs<Filter>
535  {
536  public:
537  Filter(void) {}
538 virtual ~Filter(void) {}
539 virtual void compile(sp<RecordGroup> a_rg_dataset) = 0;
540 virtual bool filter(const String &a_arg,
541  const t_r_vector &a_in, t_r_vector &a_out) = 0;
542  };
543 
544  class AccessorSetOp :
545  virtual public Op, public CastableAs<AccessorSetOp>
546  {
547  public:
548  AccessorSetOp(sp<AccessorSet> a_as);
549 virtual ~AccessorSetOp(void);
550 virtual void compile(sp<RecordGroup> a_rg_dataset);
551 virtual void process(const t_r_vector &a_in, t_r_vector &a_out);
552 
553  private:
554  sp<RecordGroup> m_rg_dataset;
555  t_r_vector m_r_vector;
556  sp<AccessorSet> m_as;
557  };
558 
559 
560  template<typename AS>
561  void add(const String &a_key)
562  {
563  sp<AS> spAS(new AS());
564  sp<AccessorSetOp> spASOP(new AccessorSetOp(spAS));
565  spASOP->compile(m_rg_dataset);
566  m_op_map[a_key] = spASOP;
567  }
568 
569  class BondOp : virtual public Op, public CastableAs<BondOp>
570  {
571  public:
572  BondOp(const String &a_left, const String &a_right);
573 virtual ~BondOp(void);
574 virtual void compile(sp<RecordGroup> a_rg_dataset);
575 virtual void process(const t_r_vector &a_in, t_r_vector &a_out);
576 
577  private:
578  String m_left;
579  String m_right;
580  sp<RecordGroup> m_rg_dataset;
581  t_r_vector m_r_vector;
582  };
583 
584  void addBond(const String &a_key, const String &a_left,
585  const String &a_right);
586 
587  class RecordGroupOp :
588  virtual public Op, public CastableAs<RecordGroupOp>
589  {
590  public:
591  RecordGroupOp(sp<RecordGroup> a_rg_inject);
592 virtual ~RecordGroupOp(void);
593 virtual void compile(sp<RecordGroup> a_rg_dataset);
594 virtual void process(const t_r_vector &a_in, t_r_vector &a_out);
595 
596  private:
597  sp<RecordGroup> m_rg_inject;
598  t_r_vector m_r_vector;
599  };
600 
601  void addRecordGroup(const String &a_key,
602  sp<RecordGroup> a_rg_inject);
603 
604  class NameFilter :
605  virtual public Filter, public CastableAs<NameFilter>
606  {
607  public:
608  NameFilter(void);
609 virtual ~NameFilter(void);
610 virtual void compile(sp<RecordGroup> a_rg_dataset);
611 virtual bool filter(const String &a_arg,
612  const t_r_vector &a_in, t_r_vector &a_out);
613  private:
614  AsNamed m_asNamed;
615  };
616 
617  class IndexFilter :
618  virtual public Filter, public CastableAs<IndexFilter>
619  {
620  public:
621  IndexFilter(void);
622 virtual ~IndexFilter(void);
623 virtual void compile(sp<RecordGroup> a_rg_dataset);
624 virtual bool filter(const String &a_arg,
625  const t_r_vector &a_in, t_r_vector &a_out);
626  private:
627  };
628  void append(sp<Filter> a_filter)
629  {
630  m_op_vector.push_back(a_filter);
631  a_filter->compile(m_rg_dataset);
632  }
633 
634  void locate(t_r_vector &a_records, const String &a_address);
635 
636  void baseAddress(const String &a_address, String &a_base,
637  String &a_attr);
638 
639  static bool arrayIndex(const String &a_input,
640  String &a_trimmed, unsigned int &a_index);
641 
642  template<typename T>
643  T *find(const String &a_address)
644  {
645  String base;
646  String attr;
647  baseAddress(a_address, base, attr);
648 
649  t_r_vector records;
650  locate(records, base);
651  if(records.size() == 0) { return NULL; }
652 
653  // final token is for bridging access to caller
654  Accessor<T> accessor(m_rg_dataset->scope(), attr);
655  for(unsigned int i = 0; i < records.size(); i++)
656  {
657  if(accessor.check(records[i]))
658  {
659  return &(accessor(records[i]));
660  }
661  }
662 
663  return NULL;
664  }
665 
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;
669  sp<RecordGroup> m_rg_dataset;
670  t_asets m_accessorSets;
671  t_op_map m_op_map;
672  t_op_vector m_op_vector;
673 };
674 
675 class FE_DL_EXPORT CanonicalStd : public Canonical
676 {
677  public:
678  CanonicalStd(void) { }
679 virtual ~CanonicalStd(void) { }
680 virtual void bind(sp<RecordGroup> a_rg_dataset);
681 };
682 
683 class FE_DL_EXPORT RealAccessor
684 {
685  public:
686  RealAccessor(void) {}
687 
688  void setup(sp<Scope> a_scope, const String &a_name);
689  bool check(const Record& r_hasreal) const;
690 
691  void set(const Record& r_hasreal, t_moa_real a_v);
692  t_moa_real get(const Record& r_hasreal);
693 
694  private:
695  Accessor<t_moa_real> m_a_real;
696  Accessor<t_moa_v2> m_a_v2;
697  Accessor<t_moa_v3> m_a_v3;
698  Accessor<t_moa_v4> m_a_v4;
699  Accessor<t_atomic_real> m_a_atomic;
700  Accessor<int> m_a_int;
701  unsigned int m_mode;
702  unsigned int m_index;
703 };
704 
705 inline sp<RecordGroup> clone(sp<RecordGroup> a_rg)
706 {
707  Cloner cloner(a_rg->scope());
708  return cloner.clone(a_rg);
709 }
710 
711 class FE_DL_EXPORT StreamableI
712  : virtual public Component,
713  public CastableAs<StreamableI>
714 {
715  public:
716 virtual void output(std::ostream &a_ostrm) = 0;
717 virtual void input(std::istream &a_istrm) = 0;
718 };
719 
720 
721 
722 template <typename T>
723 class InfoI : public BaseType::Info
724 {
725  public:
726  InfoI(sp<Registry> a_spRegistry)
727  {
728  m_spRegistry = a_spRegistry;
729  }
730  sp<Registry> m_spRegistry;
731 typedef sp<T> t_interface;
732 typedef sp<StreamableI> t_streamable;
733 virtual IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode)
734  {
735  IWORD n = 0;
736  if(mode == e_ascii)
737  {
738  t_interface &spInterface = *(t_interface *)instance;
739  t_streamable spStreamable = spInterface;
740  if(spInterface.isValid() && spStreamable.isValid())
741  {
742 
743  ostrm << "\"";
744  ostrm << spInterface->name().c_str();
745  ostrm << " \'";
746  spStreamable->output(ostrm);
747  ostrm << "\'\"";
748  }
749  else
750  {
751  ostrm << "\"invalid interface\"";
752  }
753  }
754  return (mode == e_ascii)? c_ascii: n;
755  }
756 virtual void input(std::istream &istrm, void *instance, t_serialMode mode)
757  {
758  std::string s;
759  char c;
760  while(istrm.get(c))
761  {
762  if(c == '\0')
763  {
764  break;
765  }
766  s.push_back(c);
767  }
768  String buffer = s.c_str();
769 
770  std::vector< std::string > words;
771 
772  while(!buffer.empty())
773  {
774  String word=buffer.parse("'");
775  if(!word.empty())
776  {
777  words.push_back(word.c_str());
778  }
779  }
780 
781  if(words.size() >= 2)
782  {
783  t_interface &spInterface = *(t_interface *)instance;
784 
785  spInterface = m_spRegistry->create(words[0].c_str());
786 
787  t_streamable spStreamable = spInterface;
788  if(spInterface.isValid() && spStreamable.isValid())
789  {
790  std::istringstream istrm(words[1]);
791  spStreamable->input(istrm);
792  }
793  }
794  }
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();}
801 };
802 
803 
804 template<typename T>
805 void assertInterface(sp<Master> a_spMaster, const char *a_name)
806 {
807  sp<BaseType> spT;
808  spT = a_spMaster->typeMaster()->assertType< sp<T> >(a_name);
809  spT->setInfo(new InfoI<T>(a_spMaster->registry()));
810 }
811 
812 #define AsConstruct(AS) \
813  AS(void) {} \
814  AS(Record &r){ if(r.isValid()) { bind(r.layout()->scope()); }} \
815  AS(sp<Scope> a_spScope){ bind(a_spScope); }
816 
817 class AsDatasetMeta
818  : public AccessorSet, public Initialize<AsDatasetMeta>
819 {
820  public:
821  AsConstruct(AsDatasetMeta);
822  void initialize(void)
823  {
824  add(dictionary, FE_USE("dataset:dictionary"));
825  }
827 
828  void digest(sp<RecordGroup> a_dataset)
829  {
830  m_dataset = a_dataset;
831  bind(a_dataset->scope());
832  m_all_map.clear();
833  m_r_first_meta = Record();
834  std::vector<Record> metas;
835  filter(metas, a_dataset);
836  for(Record &r_meta : metas)
837  {
838  if(!m_r_first_meta.isValid())
839  {
840  m_r_first_meta = r_meta;
841  }
842  for(std::map<String,String>::iterator i_map =
843  dictionary(r_meta).begin();
844  i_map != dictionary(r_meta).end(); i_map++)
845  {
846  m_all_map[i_map->first] = r_meta;
847  }
848  }
849  }
850  String get(const String &a_key)
851  {
852  std::map<String,Record>::iterator i_map =
853  m_all_map.find(a_key);
854 
855  if(i_map == m_all_map.end())
856  {
857  digest(m_dataset);
858  i_map = m_all_map.find(a_key);
859  if(i_map == m_all_map.end())
860  {
861  return String("__unset__") + a_key;
862  }
863  }
864 
865  return dictionary(i_map->second)[a_key];
866  }
867  void set(const String &a_key, const String &a_value)
868  {
869  std::map<String,Record>::iterator i_map =
870  m_all_map.find(a_key);
871  if(i_map == m_all_map.end())
872  {
873  if(!m_r_first_meta.isValid())
874  {
875  std::vector<Record> metas;
876  filter(metas, m_dataset);
877  if(metas.size() > 0)
878  {
879  m_r_first_meta = metas[0];
880  }
881  else
882  {
883  sp<Layout> l_first =
884  m_dataset->scope()->declare("AUTOMATIC_META");
885  populate(l_first);
886  m_r_first_meta =
887  m_dataset->scope()->createRecord(l_first);
888  m_dataset->add(m_r_first_meta);
889  }
890  }
891  dictionary(m_r_first_meta)[a_key] = a_value;
892  m_all_map[a_key] = m_r_first_meta;
893  }
894 
895  dictionary(m_all_map[a_key])[a_key] = a_value;
896 
897  }
898  Record m_r_first_meta;
899  std::map<String,Record> m_all_map;
900  sp<RecordGroup> m_dataset;
901 
902 };
903 
904 /// Associates a name with a RecordGroup
906  : public AsNamed, public Initialize<AsDataset>
907 {
908  public:
909  AsConstruct(AsDataset);
910  void initialize(void)
911  {
912  add(dataset, FE_USE("dataset:group"));
913  }
914  Accessor< sp<RecordGroup> > dataset;
915 };
916 
917 
918 class AsDatasetControl
919  : public AsNamed, public Initialize<AsDatasetControl>
920 {
921  public:
922  AsConstruct(AsDatasetControl);
923  void initialize(void)
924  {
925  add(active, FE_USE("dataset:active"));
926  }
927  Accessor< bool > active;
928 };
929 
930 class AsDatasetMixer
931  : public AsNamed, public Initialize<AsDatasetMixer>
932 {
933  public:
934  AsConstruct(AsDatasetMixer);
935  void initialize(void)
936  {
937  add(inputs, FE_USE("mixer:inputs"));
938  }
939  Accessor< Array<String> > inputs;
940 };
941 
942 class AsDatasetManyToMany
943  : public AccessorSet, public Initialize<AsDatasetManyToMany>
944 {
945  public:
946  AsConstruct(AsDatasetManyToMany);
947  void initialize(void)
948  {
949  add(left, FE_USE("mixer:left"));
950  add(right, FE_USE("mixer:right"));
951  add(active, FE_USE("dataset:active"));
952  }
954  Accessor< Array<String> > right;
955  Accessor< bool > active;
956 };
957 
958 class AsAspect
959  : public AccessorSet, public Initialize<AsAspect>
960 {
961  public:
962  AsConstruct(AsAspect);
963  void initialize(void)
964  {
965  add(label, FE_USE("aspect:label"));
966  }
967  Accessor<String> label;
968 };
969 
970 class FE_DL_EXPORT Overlayer
971 {
972  public:
973  Overlayer(sp<Scope> a_spScope);
974 virtual ~Overlayer(void) {}
975 
976 
977  void load(const char *a_str)
978  {
979  sp<data::StreamI> spStreamDataset;
980  std::ifstream strm(a_str);
981  spStreamDataset=new data::AsciiStream(m_rg_baseline->scope());
982  sp<RecordGroup> rg_file = spStreamDataset->input(strm);
983  strm.close();
984  m_rg_baseline->add(rg_file);
985  }
986  void load(sp<RecordGroup> a_rg_file)
987  {
988  m_rg_baseline->add(a_rg_file);
989  }
990 
991  std::vector< sp<RecordGroup> > &bakedDatasets(void)
992  {
993  if(!m_built)
994  {
995  build();
996  }
997  return m_rgs_baked;
998  }
999 
1000  RecordDictionary<AsDataset> &datasets(void) { return m_datasets; }
1001 
1002  sp<RecordGroup> baseline(void) { return m_rg_baseline; }
1003 
1004  void build(void);
1005  private:
1006  void manyToMany(void);
1007  void mixdown(void);
1008  void bakeControls(void);
1009 
1010  private:
1011  RecordDictionary<AsDataset> m_datasets;
1012  sp<RecordGroup> m_rg_baseline;
1013  std::vector< sp<RecordGroup> > m_rgs_baked;
1014  sp<Scope> m_spScope;
1015  bool m_built;
1016 };
1017 
1018 inline void loadFileIntoRG(sp<RecordGroup> a_spRG, const char *a_str)
1019 {
1020  sp<data::StreamI> spStreamDataset;
1021  std::ifstream strm(a_str);
1022  spStreamDataset=new data::AsciiStream(a_spRG->scope());
1023  sp<RecordGroup> rg_file = spStreamDataset->input(strm);
1024  strm.close();
1025  a_spRG->add(rg_file);
1026 }
1027 
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)
1036 
1037 void dump(const char *a_msg);
1038 void dump(int a_flags, const char *a_msg);
1039 //void dump(const char *a_msg, int a_i);
1040 //void dump(int a_flags, const char *a_msg, int a_i);
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);
1049 
1050 void dump(const char *a_msg, Record a_r);
1051 void dump(int a_flags, const char *a_msg, Record a_r);
1052 
1053 } /* namespace ext */
1054 } /* namespace fe */
1055 
1056 // t_atomic_real needs some type system specialization to deal with restrictions
1057 namespace fe
1058 {
1059 
1060 template <>
1061 class FE_DL_EXPORT TypeVector<::fe::ext::t_atomic_real> :
1062  public BaseTypeVector
1063  //, public CastableAs< TypeVector<int> >
1064 {
1065  public:
1066  TypeVector(void)
1067  {
1068  m_base = NULL;
1069  m_size = sizeof(::fe::ext::t_atomic_real);
1070  m_count_alloc = 0;
1071  m_count_used = 0;
1072  m_vector = NULL;
1073  }
1074 virtual ~TypeVector(void)
1075  {
1076  if(m_vector) { delete [] m_vector; }
1077  }
1078 
1079 virtual void resize(unsigned int a_size)
1080  {
1081  if(a_size == 0)
1082  {
1083  if(m_vector)
1084  {
1085  delete [] m_vector;
1086  m_vector = NULL;
1087  m_base = NULL;
1088  m_count_alloc = 0;
1089  }
1090  }
1091  else if(a_size > m_count_used)
1092  {
1093  if(a_size > m_count_alloc)
1094  {
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];
1099  m_base = m_vector;
1100  for(unsigned int i = 0; i < m_count_used; i++)
1101  {
1102  ::fe::ext::t_moa_real intermediary = from[i];
1103  m_vector[i] = intermediary;
1104  }
1105  delete [] from;
1106  m_count_alloc = new_alloc;
1107  }
1108  for(unsigned int i = m_count_used; i < a_size; i++)
1109  {
1110  m_vector[i] = 0.0;
1111  }
1112  }
1113  m_count_used = a_size;
1114  }
1115 
1116 virtual void *raw_at(unsigned int a_index)
1117  {
1118  return (void *)&m_vector[a_index];
1119  }
1120 
1121  ::fe::ext::t_atomic_real &at(unsigned int a_index)
1122  {
1123  return m_vector[a_index];
1124  }
1125 
1126  private:
1127  ::fe::ext::t_atomic_real *m_vector;
1128  unsigned int m_count_alloc;
1129  unsigned int m_count_used;
1130 };
1131 
1132 
1133 template <>
1134 inline void Type<::fe::ext::t_atomic_real>::assign(void *lvalue, void *rvalue)
1135 {
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;
1139 }
1140 
1141 template <>
1143 {
1144  sp< BaseTypeVector > spBTV(new TypeVector<::fe::ext::t_atomic_real>);
1145  return spBTV;
1146 }
1147 
1148 class EvalRange
1149 {
1150  public:
1151  EvalRange(const Array<String> &a_args)
1152  {
1153  assert(a_args.size() >= 3);
1154 
1155  m_mode = 0;
1156  m_start = a_args[0].real();
1157  m_end = a_args[1].real();
1158  if(a_args[2].c_str()[0] == '*')
1159  {
1160  String n = a_args[2].prechop("*");
1161  m_incr = n.real();
1162  m_mode = 1;
1163  }
1164  else
1165  {
1166  m_incr = a_args[2].real();
1167  }
1168  }
1169  EvalRange(void)
1170  {
1171  m_mode = 0;
1172  m_start = 0.0;
1173  m_end = 0.0;
1174  m_incr = 1.0;
1175  }
1176 
1177  class iterator
1178  {
1179  friend class EvalRange;
1180  public:
1181  iterator(void)
1182  {
1183  m_value = 0.0;
1184  m_end = true;
1185  }
1186  iterator(const iterator& it)
1187  {
1188  m_value = it.m_value;
1189  m_end = it.m_end;
1190  }
1191  ::fe::ext::t_moa_real &operator*(void)
1192  {
1193  return m_value;
1194  }
1195  ::fe::ext::t_moa_real *operator->(void)
1196  {
1197  return &m_value;
1198  }
1199  iterator operator++()
1200  {
1201  increment();
1202  check_for_end();
1203  return *this;
1204  }
1205  iterator operator++(int dummy)
1206  {
1207  increment();
1208  check_for_end();
1209  return *this;
1210  }
1211  bool operator==(const iterator &other)
1212  {
1213  return (m_end == other.m_end);
1214  }
1215  bool operator!=(const iterator &other)
1216  {
1217  return (m_end != other.m_end);
1218  }
1219 
1220  void increment(void)
1221  {
1222  if(m_pRange->m_mode == 1)
1223  {
1224  m_value = m_value * m_pRange->m_incr;
1225  }
1226  else
1227  {
1228  m_value = m_value + m_pRange->m_incr;
1229  }
1230  }
1231  void check_for_end(void)
1232  {
1233  if(m_pRange->m_end >= m_pRange->m_start)
1234  {
1235  if(m_value > m_pRange->m_end) { m_end = true; }
1236  }
1237  else
1238  {
1239  if(m_value < m_pRange->m_end) { m_end = true; }
1240  }
1241  }
1242 
1243  ::fe::ext::t_moa_real m_value;
1244  bool m_end;
1245  EvalRange *m_pRange;
1246  };
1247 
1248  iterator begin(void)
1249  {
1250  iterator it;
1251  it.m_end = false;
1252  it.m_value = m_start;
1253  it.m_pRange = this;
1254  it.check_for_end();
1255  return it;
1256  }
1257  iterator end(void)
1258  {
1259  iterator it;
1260  it.m_pRange = this;
1261  return it;
1262  }
1263 
1264  ::fe::ext::t_moa_real operator[] (int i)
1265  {
1266  if(i == 0) { return m_start; }
1267  else if(i == 1) { return m_end; }
1268  else if(i == 2) { return m_incr; }
1269  return 0.0;
1270  }
1271 
1272  ::fe::ext::t_moa_real m_start;
1273  ::fe::ext::t_moa_real m_end;
1274  ::fe::ext::t_moa_real m_incr;
1275  int m_mode;
1276 };
1277 
1278 template<>
1279 inline bool Type<::fe::ext::t_note_perform_tmp>::equiv(void *a_a, void *a_b)
1280 {
1281  return true;
1282 }
1283 
1284 inline void snapshot(sp<RecordGroup> a_spRG, const char *a_str)
1285 {
1286  sp<data::StreamI> spStream;
1287  spStream=new data::AsciiStream(a_spRG->scope());
1288  std::ofstream asciifile(a_str);
1289  spStream->output(asciifile, a_spRG);
1290  asciifile.close();
1291 }
1292 
1293 } /* namespace fe */
1294 
1295 #endif /* __moa_data_h__ */
1296 
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&#39;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&#39;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