Free Electron
Type.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 __core_Type_h__
8 #define __core_Type_h__
9 
10 //* NOTE already stored for FE_COUNTED_STORE_TRACKER
11 #define FE_TYPE_STORE_NAME (FE_CODEGEN<=FE_DEBUG && !FE_COUNTED_STORE_TRACKER)
12 
13 namespace fe
14 {
15 
16 /** @brief C++ type_info wrapper
17 
18  @ingroup core
19  */
20 class FE_DL_EXPORT TypeInfo
21 {
22  public:
23  class not_initialized {};
24 
25  TypeInfo(void);
26  TypeInfo(const fe_type_info &other);
27  TypeInfo(const TypeInfo &other);
28 
29  template<typename X>
30  void assign(void) { operator=(getTypeId<X>()); }
31 
32  const fe_type_info &ref(void) const;
33 
34  TypeInfo &operator=(const TypeInfo &other);
35  bool operator==(const TypeInfo &other) const;
36  bool operator!=(const TypeInfo &other) const;
37  bool operator<(const TypeInfo &other) const;
38  bool operator>(const TypeInfo &other) const;
39  bool operator>=(const TypeInfo &other) const;
40  bool operator<=(const TypeInfo &other) const;
41 
42  bool isValid(void) const;
43  private:
44  const fe_type_info *m_pTypeInfo;
45 };
46 
47 class FE_DL_EXPORT BaseTypeVector:
48  public Counted,
49  public CastableAs<BaseTypeVector>
50 {
51  public:
52  BaseTypeVector(void)
53  {
54  m_base = NULL;
55  m_size = 0;
56  }
57 virtual ~BaseTypeVector(void)
58  {
59  }
60 
61 //virtual void *vectorRoot(void) = 0;
62 //virtual size_t itemSize(void) = 0;
63 virtual void resize(unsigned int a_size) {}
64 
65  // raw_at cannot be a virtual due to speed issues
66  void *raw_at(unsigned int a_index)
67  {
68  return (void *)((char *)m_base + m_size*a_index);
69  }
70 
71 #if FE_COUNTED_STORE_TRACKER
72 const String verboseName(void) const
73  { return "BaseTypeVector "+name(); }
74 #endif
75 
76  unsigned int size(void) const { return m_size; }
77 
78  protected:
79  void *m_base;
80  unsigned int m_size;
81 };
82 
83 /** @brief A class to associate functionality with run time types.
84 
85  @ingroup core
86 
87  The primary purpose of this class is to associate functionaility such
88  as serialization, construction, and destruction with library/application
89  managed instances of C++ types.
90 
91  This is done by creating a BaseType, typically by using the Type template
92  class through TypeMaster. The necessary functionality is associated by
93  creating a BaseType::Info object and attaching it to the BaseType.
94 
95  @code
96  class Info32 : public BaseType::Info
97  {
98  virtual void output(std::ostream &ostrm, void *instance, t_serialMode mode)
99  {
100  U32 u32;
101  u32 = htonl(*(U32 *)instance);
102  ostrm.write((char *)&u32, sizeof(U32));
103  }
104  virtual void input(std::istream &istrm, void *instance, t_serialMode mode)
105  {
106  U32 u32;
107  istrm.read((char *)&u32, sizeof(U32));
108  *(U32 *)instance = ntohl(u32);
109  }
110  virtual IWORD iosize(void) { return sizeof(U32); }
111  };
112 
113  sp<BaseType> spT;
114  spT = typeMaster->assertType<U32>("unsigned_integer");
115  spT->setInfo(new Info32());
116 
117  @endcode
118 
119  */
120 class FE_DL_EXPORT BaseType : public Counted, public ClassSafe<GlobalHolder>
121 {
122  public:
123  class FE_DL_PUBLIC FE_CORE_PORT Info:
124  virtual public Counted,
125  public CastableAs<Info>
126  {
127  public:
128  typedef enum
129  {
130  e_binary,
131  e_ascii
132  } t_serialMode;
133  Info(void)
134  {
135 #if FE_COUNTED_STORE_TRACKER
136  setName("BaseType::Info");
137 #endif
138 #if FE_CODEGEN<=FE_DEBUG && FE_OS==FE_LINUX && FE_HEAP_CHECKABLE
139  U8 current_stack;
140  if((void*)this>(void*)&current_stack)
141  feX("fe::BaseType::Info::Info",
142  "Info object not on stack");
143 #endif
144  suppressReport();
145  }
146  virtual ~Info(void) {}
147  virtual bool getConstruct(void) { return false; }
148  virtual void construct(void *instance) {}
149  virtual void destruct(void *instance) {}
150  virtual BWORD copy(void *instance,const void* source)
151  {
152  if(iosize()==c_implicit)
153  return FALSE;
154  memcpy(instance,source,iosize());
155  return TRUE;
156  }
157  virtual IWORD output( std::ostream &ostrm, void *instance,
158  t_serialMode mode) = 0;
159  virtual void input( std::istream &istrm, void *instance,
160  t_serialMode mode) = 0;
161  virtual String print(void *instance) { return String(); }
162  virtual IWORD iosize(void) { return c_implicit; }
163  virtual FE_UWORD alignment(void) { return 0; }
164 
165  /** implicit variable size. avoid. mainly for internal use. */
166  static FE_DL_PUBLIC const IWORD c_implicit;
167  /** explicit variable size. network byte order 32 bit unsigned
168  integer should follow */
169  static FE_DL_PUBLIC const IWORD c_explicit;
170  static FE_DL_PUBLIC const IWORD c_noascii;
171  static FE_DL_PUBLIC const IWORD c_ascii;
172 
173 #if FE_COUNTED_STORE_TRACKER
174  const String verboseName(void) const
175  { return "BaseType::Info "+name(); }
176 #endif
177  };
178  public:
179  BaseType(void);
180 virtual ~BaseType(void);
181 virtual FE_UWORD size(void) const;
182 virtual void assign(void *lvalue, void *rvalue) =0;
183 virtual bool equiv(void *a_a, void *a_b) =0;
184 virtual void setInfo(const sp<Info> &spInfo);
185 virtual void setInfo(Info *pInfo);
186 virtual sp<Info> getInfo(void);
187 
188 virtual bool getConstruct(void) const;
189 virtual void construct(void *instance);
190 virtual void destruct(void *instance);
191 virtual BWORD copy(void *instance,const void* source);
192 virtual TypeInfo &typeinfo(void);
193 virtual sp<BaseTypeVector> createVector(void) =0;
194 
195 
196 #if FE_COUNTED_STORE_TRACKER || FE_TYPE_STORE_NAME
197 const String verboseName(void) const { return "Type<"+name()+">"; }
198 #endif
199 
200 #if FE_TYPE_STORE_NAME
201 virtual
202 const String& name(void) const { return m_storedName; }
203  void setName(const String& a_name)
204  { m_storedName=a_name; }
205  private:
206  String m_storedName;
207 #endif
208 
209  protected:
210  FE_UWORD m_size;
211  sp<Info> m_spInfo;
212  TypeInfo m_typeInfo;
213 };
214 
215 
216 template <class T>
217 class FE_DL_EXPORT TypeInfoInitialized : public BaseType::Info
218 {
219  public:
220  TypeInfoInitialized(void)
221  {
222 #if FE_COUNTED_STORE_TRACKER
223  setName(FE_TYPESTRING(T));
224 #endif
225  }
226 virtual ~TypeInfoInitialized(void) { }
227 virtual bool getConstruct(void) { return true; }
228 virtual void construct(void *instance) { *((T *)instance)=T(0); }
229 virtual IWORD output( std::ostream &ostrm, void *instance,
230  t_serialMode mode)
231  {
232  if(mode == e_binary) { return 0; }
233  else { return c_noascii; }
234  }
235 virtual void input( std::istream &istrm, void *instance,
236  t_serialMode mode) { }
237 virtual IWORD iosize(void) { return sizeof(T); }
238 };
239 
240 template <class T>
241 class FE_DL_EXPORT TypeInfoConstructable : public BaseType::Info
242 {
243  public:
244  TypeInfoConstructable(void)
245  {
246 #if FE_COUNTED_STORE_TRACKER
247  setName(FE_TYPESTRING(T));
248 #endif
249  }
250 virtual ~TypeInfoConstructable(void) { }
251 virtual bool getConstruct(void) { return true; }
252 virtual void construct(void *instance) { new(instance)T; }
253 virtual void destruct(void *instance) { ((T *)instance)->~T(); }
254 virtual IWORD output( std::ostream &ostrm, void *instance,
255  t_serialMode mode)
256  {
257  if(mode == e_binary) { return 0; }
258  else { return c_noascii; }
259  }
260 virtual void input( std::istream &istrm, void *instance,
261  t_serialMode mode) { }
262 };
263 
264 class FE_DL_EXPORT BaseTypeInfoArray:
265  virtual public Counted,
266  public CastableAs<BaseTypeInfoArray>
267 {
268  public:
269  BaseTypeInfoArray(void) {}
270 virtual ~BaseTypeInfoArray(void) {}
271 
272  //* changes buffer size
273 virtual void resize(I32 a_size, void *instance) =0;
274 
275  //* set buffer pointer and returns size
276 virtual I32 access(void*& a_rpBuffer, void *instance) =0;
277 };
278 
279 //* NOTE T is Array<typename> or interchangeable std::vector<typename>
280 template <class T>
281 class FE_DL_EXPORT TypeInfoArray:
282  public TypeInfoConstructable<T>,
283  public BaseTypeInfoArray
284 {
285  public:
286  TypeInfoArray(void) {}
287 virtual ~TypeInfoArray(void) {}
288 
289 virtual void resize(I32 a_size, void *instance)
290  {
291  if(!instance) return;
292  T &v = *(T *)instance;
293  v.resize(a_size);
294  }
295 
296 virtual I32 access(void*& a_rpBuffer, void *instance)
297  {
298  if(!instance) return -1;
299  T &v = *(T *)instance;
300  a_rpBuffer=v.data();
301  return v.size();
302  }
303 };
304 
305 template <class T>
306 class FE_DL_EXPORT TypeInfoMemcpyIO : public BaseType::Info
307 {
308  public:
309 virtual IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode);
310 virtual void input(std::istream &istrm, void *instance, t_serialMode mode);
311 virtual IWORD iosize(void);
312 };
313 
314 #if 0
315 template <class T>
316 class FE_DL_EXPORT TypeVector : public BaseTypeVector
317 {
318  public:
319  TypeVector(void)
320  {
321  m_base = NULL;
322  m_vector = NULL;
323  m_size = sizeof(T);
324  }
325 virtual ~TypeVector(void)
326  {
327  if(m_vector)
328  {
329  deallocate(m_vector);
330  }
331  }
332 
333 virtual void resize(unsigned int a_size)
334  {
335  if(m_vector && a_size == 0)
336  {
337  deallocate(m_vector);
338  m_vector = NULL;
339  m_base = NULL;
340  return;
341  }
342  if(!m_vector)
343  {
344  m_vector = (T *)allocate(a_size*m_size);
345  }
346  else
347  {
348  m_vector = (T *)reallocate((void *)m_vector, a_size*m_size);
349  }
350  m_base = m_vector;
351  }
352 
353 virtual void *raw_at(unsigned int a_index)
354  {
355  return (void *)&m_vector[a_index];
356  }
357 
358  T &at(unsigned int a_index)
359  {
360  return m_vector[a_index];
361  }
362 
363  private:
364  T *m_vector;
365 };
366 #endif
367 
368 
369 #if 1
370 template <class T>
371 class FE_DL_EXPORT TypeVector:
372  public BaseTypeVector,
373  public CastableAs< TypeVector<T> >
374 {
375  public:
376  TypeVector(void)
377  {
378  m_base = NULL;
379  m_size = sizeof(T);
380  //TODO: 1000 seems grossly arbitrary
381  m_vector.reserve(1000);
382  }
383 virtual ~TypeVector(void)
384  {
385 #if FE_COUNTED_STORE_TRACKER
386  if(m_base)
387  {
388  deregisterRegion(m_base);
389  }
390 #endif
391  }
392 
393 virtual void resize(unsigned int a_size)
394  {
395 #if FE_COUNTED_STORE_TRACKER
396  if(m_base)
397  {
398  deregisterRegion(m_base);
399  }
400 #endif
401 
402  m_vector.resize(a_size);
403  if(a_size > 0)
404  {
405  m_base = (void *)&(m_vector[0]);
406  }
407 
408 #if FE_COUNTED_STORE_TRACKER
409  registerRegion(m_base,a_size*m_size);
410 #endif
411  }
412 
413 virtual void *raw_at(unsigned int a_index)
414  {
415  return (void *)&m_vector[a_index];
416  }
417 
418  T &at(unsigned int a_index)
419  {
420  return m_vector[a_index];
421  }
422 
423 #if FE_COUNTED_STORE_TRACKER
424 const String verboseName(void) const { return "TypeVector "+name(); }
425 #endif
426 
427  private:
428  Array<T> m_vector;
429 };
430 
431 
432 // work around stupid STL decision to specialize std::vector<bool>
433 template <>
434 class FE_DL_EXPORT TypeVector<bool> : public BaseTypeVector
435 {
436  public:
437  TypeVector(void)
438  {
439  m_base = NULL;
440  m_vector = NULL;
441  m_size = sizeof(bool);
442  }
443 virtual ~TypeVector(void)
444  {
445  if(m_vector)
446  {
447  deallocate(m_vector);
448  }
449  }
450 
451 virtual void resize(unsigned int a_size)
452  {
453  if(m_vector && a_size == 0)
454  {
455  deallocate(m_vector);
456  m_vector = NULL;
457  m_base = NULL;
458  return;
459  }
460  if(!m_vector)
461  {
462  m_vector = (bool *)allocate(a_size*m_size);
463  }
464  else
465  {
466  m_vector = (bool *)reallocate((void *)m_vector, a_size*m_size);
467  }
468  m_base = m_vector;
469  }
470 
471 virtual void *raw_at(unsigned int a_index)
472  {
473  return (void *)&m_vector[a_index];
474  }
475 
476  bool &at(unsigned int a_index)
477  {
478  return m_vector[a_index];
479  }
480 
481  private:
482  bool *m_vector;
483 };
484 #endif
485 
486 template <typename T>
487 class FE_DL_EXPORT TypeVector< std::atomic<T> > :
488  public BaseTypeVector,
489  public CastableAs< TypeVector< std::atomic<T> > >
490 {
491 
492 
493  public:
494  TypeVector(void)
495  {
496  m_base = NULL;
497  m_size = sizeof(std::atomic<T>);
498  m_count_alloc = 0;
499  m_count_used = 0;
500  m_vector = NULL;
501  }
502 virtual ~TypeVector(void)
503  {
504  if(m_vector) { delete [] m_vector; }
505  }
506 
507 virtual void resize(unsigned int a_size)
508  {
509  if(a_size == 0)
510  {
511  if(m_vector)
512  {
513  delete [] m_vector;
514  m_vector = NULL;
515  m_base = NULL;
516  m_count_alloc = 0;
517  }
518  }
519  else if(a_size > m_count_used)
520  {
521  if(a_size > m_count_alloc)
522  {
523  unsigned int new_alloc = 1;
524  if(m_count_alloc > 0) { new_alloc = m_count_alloc * 2; }
525  if(m_count_alloc < a_size) { new_alloc = a_size; }
526  std::atomic<T> *from = m_vector;
527  m_vector = new std::atomic<T>[new_alloc];
528  m_base = m_vector;
529  for(unsigned int i = 0; i < m_count_used; i++)
530  {
531  T intermediary = from[i];
532  m_vector[i] = intermediary;
533  }
534  delete [] from;
535  m_count_alloc = new_alloc;
536  }
537  for(unsigned int i = m_count_used; i < a_size; i++)
538  {
539  m_vector[i] = T();
540  }
541  }
542  m_count_used = a_size;
543  FEASSERT(m_count_used<=m_count_alloc);
544  }
545 
546 virtual void *raw_at(unsigned int a_index)
547  {
548  return (void *)&m_vector[a_index];
549  }
550 
551  std::atomic<T> &at(unsigned int a_index)
552  {
553  FEASSERT(a_index<m_count_alloc);
554  FEASSERT(a_index<m_count_used);
555  return m_vector[a_index];
556  }
557 
558  private:
559  std::atomic<T> *m_vector;
560  unsigned int m_count_alloc;
561  unsigned int m_count_used;
562 };
563 
564 /** @brief A class to associate functionality with run time types.
565 
566  @ingroup core
567 
568  See BaseType for details.
569  */
570 template <class T>
571 class FE_DL_EXPORT Type : public BaseType
572 {
573  public:
574  Type(void);
575 virtual ~Type(void);
576 virtual void assign(void *lvalue, void *rvalue);
577 virtual bool equiv(void *a_a, void *a_b);
578 static Type<T>* create(void);
579 virtual sp<BaseTypeVector> createVector(void);
580 };
581 
582 template <typename T>
583 class FE_DL_EXPORT Type< std::atomic<T> > : public BaseType
584 {
585  public:
586  Type(void);
587 virtual ~Type(void);
588 virtual void assign(void *lvalue, void *rvalue);
589 virtual bool equiv(void *a_a, void *a_b);
590 static Type< std::atomic<T> >* create(void);
591 virtual sp<BaseTypeVector> createVector(void);
592 };
593 
594 template <class T>
596 {
597  sp< BaseTypeVector > spBTV(new TypeVector<T>);
598  return spBTV;
599 }
600 
601 template <>
603 {
604  sp< BaseTypeVector > spBTV(new BaseTypeVector());
605  return spBTV;
606 }
607 
608 
609 template <class T>
610 inline Type<T>::Type(void)
611 {
612  m_size=sizeof(T);
613  m_typeInfo.assign<T>();
614 #if FE_COUNTED_STORE_TRACKER || FE_TYPE_STORE_NAME
615  setName(m_typeInfo.ref().name());
616 #endif
617 }
618 
619 template <typename T>
620 inline Type< std::atomic<T> >::Type(void)
621 {
622  m_size=sizeof(std::atomic<T>);
623  m_typeInfo.assign< std::atomic<T> >();
624 #if FE_COUNTED_STORE_TRACKER || FE_TYPE_STORE_NAME
625  setName(m_typeInfo.ref().name());
626 #endif
627 }
628 
629 template <class T>
630 inline Type<T>::~Type(void)
631 {
632 }
633 
634 template <typename T>
635 inline Type< std::atomic<T> >::~Type(void)
636 {
637 }
638 
639 template <typename T>
640 inline void Type< std::atomic<T> >::assign(void *lvalue, void *rvalue)
641 {
642  T value =
643  *(reinterpret_cast<std::atomic<T> *>(rvalue));
644  *(reinterpret_cast<std::atomic<T> *>(lvalue)) = value;
645 }
646 
647 template <typename T>
648 inline sp<BaseTypeVector> Type< std::atomic<T> >::createVector(void)
649 {
650  sp< BaseTypeVector > spBTV(new TypeVector< std::atomic<T> >);
651  return spBTV;
652 }
653 
654 template <typename T>
655 inline bool Type< std::atomic<T> >::equiv(void *a_a, void *a_b)
656 {
657  return (*(reinterpret_cast<std::atomic<T> *>(a_a)) == *(reinterpret_cast<std::atomic<T> *>(a_b)));
658 }
659 
660 template <class T>
661 inline void Type<T>::assign(void *lvalue, void *rvalue)
662 { *(reinterpret_cast<T *>(lvalue)) = *(reinterpret_cast<T *>(rvalue)); }
663 
664 template <class T>
665 inline bool Type<T>::equiv(void *a_a, void *a_b)
666 {
667  return (*(reinterpret_cast<T *>(a_a)) == *(reinterpret_cast<T *>(a_b)));
668 }
669 
670 template <class T>
671 inline Type<T>* Type<T>::create(void)
672 {
673  Type<T>* pType=new Type<T>;
674  pType->registerRegion(pType,sizeof(Type<T>));
675 // feLog("Type< %s >::create %p %p %p %s\n",
676 // FE_TYPESTRING(T).c_str(),
677 // &create,pType,pType->typeinfo().ref().name(),
678 // pType->typeinfo().ref().name());
679  return pType;
680 }
681 
682 template <typename T>
683 inline Type< std::atomic<T> >* Type< std::atomic<T> >::create(void)
684 {
686  pType->registerRegion(pType,sizeof(Type< std::atomic<T> >));
687  return pType;
688 }
689 
690 template<>
691 inline void Type<void>::assign(void *lvalue, void *rvalue)
692 { }
693 
694 template<>
695 inline bool Type<void>::equiv(void *a_a, void *a_b)
696 {
697  return true;
698 }
699 
700 template<>
701 inline Type<void>::Type(void)
702 {
703  m_size=0;
704  m_typeInfo.assign<void>();
705 }
706 
707 inline FE_UWORD BaseType::size(void) const
708 {
709  SAFEGUARDCLASS;
710  return m_size;
711 }
712 
713 template <class T>
714 inline IWORD TypeInfoMemcpyIO<T>::output(std::ostream &ostrm, void *instance,
715  t_serialMode mode)
716 {
717  if(mode == e_binary)
718  {
719  ostrm.write((char *)instance, sizeof(T));
720  return sizeof(T);
721  }
722  return c_noascii;
723 }
724 
725 template <class T>
726 inline void TypeInfoMemcpyIO<T>::input(std::istream &ostrm, void *instance,
727  t_serialMode mode)
728 {
729  ostrm.read((char *)instance, sizeof(T));
730 }
731 
732 template <class T>
733 inline IWORD TypeInfoMemcpyIO<T>::iosize(void)
734 {
735  return sizeof(T);
736 }
737 
738 inline TypeInfo::TypeInfo(void)
739 {
740  m_pTypeInfo = &getTypeId<not_initialized>();
741  FEASSERT(m_pTypeInfo);
742 }
743 
744 inline TypeInfo::TypeInfo(const fe_type_info &other)
745 {
746  m_pTypeInfo = &other;
747  FEASSERT(m_pTypeInfo);
748 }
749 
750 inline TypeInfo::TypeInfo(const TypeInfo &other)
751 {
752  m_pTypeInfo = other.m_pTypeInfo;
753  FEASSERT(m_pTypeInfo);
754 }
755 
756 inline TypeInfo &TypeInfo::operator=(const TypeInfo &other)
757 {
758  if(this != &other)
759  {
760  m_pTypeInfo = other.m_pTypeInfo;
761  }
762  FEASSERT(m_pTypeInfo);
763  return *this;
764 }
765 
766 inline const fe_type_info &TypeInfo::ref(void) const
767 {
768  FEASSERT(m_pTypeInfo);
769  return *m_pTypeInfo;
770 }
771 
772 inline bool TypeInfo::isValid(void) const
773 {
774  return (bool)(ref() != getTypeId<not_initialized>());
775 }
776 
777 #if defined(GCC_HASCLASSVISIBILITY) || FE_RTTI_HOMEBREW == 1
778 inline bool TypeInfo::operator==(const TypeInfo &other) const
779 {
780  const char* n1=ref().name();
781  const char* n2=other.ref().name();
782  return n1==n2 || !strcmp(n1,n2);
783 }
784 
785 inline bool TypeInfo::operator!=(const TypeInfo &other) const
786 {
787  return !(*this==other);
788 }
789 
790 inline bool TypeInfo::operator<(const TypeInfo &other) const
791 {
792  const char* n1=ref().name();
793  const char* n2=other.ref().name();
794  return strcmp(n1,n2)<0;
795 }
796 
797 inline bool TypeInfo::operator>(const TypeInfo &other) const
798 {
799  const char* n1=ref().name();
800  const char* n2=other.ref().name();
801  return strcmp(n1,n2)>0;
802 }
803 
804 inline bool TypeInfo::operator>=(const TypeInfo &other) const
805 {
806  return !(*this<other);
807 }
808 
809 inline bool TypeInfo::operator<=(const TypeInfo &other) const
810 {
811  return !(*this>other);
812 }
813 #else
814 inline bool TypeInfo::operator==(const TypeInfo &other) const
815 {
816  return ref() == other.ref();
817 }
818 
819 inline bool TypeInfo::operator!=(const TypeInfo &other) const
820 {
821  return ref() != other.ref();
822 }
823 
824 inline bool TypeInfo::operator<(const TypeInfo &other) const
825 {
826  return ref().before(other.ref());
827 }
828 
829 inline bool TypeInfo::operator>(const TypeInfo &other) const
830 {
831  return other.ref().before(ref());
832 }
833 
834 inline bool TypeInfo::operator>=(const TypeInfo &other) const
835 {
836  return !(ref().before(other.ref()));
837 }
838 
839 inline bool TypeInfo::operator<=(const TypeInfo &other) const
840 {
841  return !(other.ref().before(ref()));
842 }
843 #endif
844 
845 struct eq_type_info
846 {
847  bool operator()(const TypeInfo &t1, const TypeInfo &t2) const
848  {
849  return t1 == t2;
850  }
851 };
852 
853 struct hash_type_info
854 {
855  FE_UWORD operator()(const TypeInfo &t) const
856  {
857  FE_UWORD hash = 0;
858  FE_UWORD len = strlen(t.ref().name());
859  for(FE_UWORD i = 0; i < len; i++)
860  { hash = (hash << 3) + t.ref().name()[i]; }
861  return hash;
862  }
863 };
864 
865 template<typename U>
866 class AutoHashMap< TypeInfo, U >:
867  public HashMap< TypeInfo, U, hash_type_info, eq_type_info > {};
868 
869 } /* namespace */
870 
871 #endif /* __core_Type_h__ */
Class level locking for thread safety.
Definition: Safe.h:213
Heap-based support for classes participating in fe::ptr <>
Definition: Counted.h:35
kernel
Definition: namespace.dox:3
BWORD operator!=(const DualString &s1, const DualString &s2)
Compare two DualString&#39;s (reverse logic)
Definition: DualString.h:229
C++ type_info wrapper.
Definition: Type.h:20
A class to associate functionality with run time types.
Definition: Type.h:571
A class to associate functionality with run time types.
Definition: Type.h:120
BWORD operator==(const DualString &s1, const DualString &s2)
Compare two DualString&#39;s.
Definition: DualString.h:208
Automatically reference-counted string container.
Definition: String.h:128
Wrapper for std::vector.
Definition: Array.h:21
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192