Free Electron
Type.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2015 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 : public Counted
48 {
49  public:
50  BaseTypeVector(void)
51  {
52  m_base = NULL;
53  m_size = 0;
54  }
55 virtual ~BaseTypeVector(void)
56  {
57  }
58 
59 //virtual void *vectorRoot(void) = 0;
60 //virtual size_t itemSize(void) = 0;
61 virtual void resize(unsigned int a_size) {}
62 
63  // raw_at cannot be a virtual due to speed issues
64  void *raw_at(unsigned int a_index)
65  {
66  return (void *)((char *)m_base + m_size*a_index);
67  }
68 
69 #if FE_COUNTED_STORE_TRACKER
70 const String verboseName(void) const
71  { return "BaseTypeVector "+name(); }
72 #endif
73 
74  unsigned int size(void) const { return m_size; }
75 
76  protected:
77  void *m_base;
78  unsigned int m_size;
79 };
80 
81 /** @brief A class to associate functionality with run time types.
82 
83  @ingroup core
84 
85  The primary purpose of this class is to associate functionaility such
86  as serialization, construction, and destruction with library/application
87  managed instances of C++ types.
88 
89  This is done by creating a BaseType, typically by using the Type template
90  class through TypeMaster. The necessary functionality is associated by
91  creating a BaseType::Info object and attaching it to the BaseType.
92 
93  @code
94  class Info32 : public BaseType::Info
95  {
96  virtual void output(std::ostream &ostrm, void *instance, t_serialMode mode)
97  {
98  U32 u32;
99  u32 = htonl(*(U32 *)instance);
100  ostrm.write((char *)&u32, sizeof(U32));
101  }
102  virtual void input(std::istream &istrm, void *instance, t_serialMode mode)
103  {
104  U32 u32;
105  istrm.read((char *)&u32, sizeof(U32));
106  *(U32 *)instance = ntohl(u32);
107  }
108  virtual IWORD iosize(void) { return sizeof(U32); }
109  };
110 
111  sp<BaseType> spT;
112  spT = typeMaster->assertType<U32>("unsigned_integer");
113  spT->setInfo(new Info32());
114 
115  @endcode
116 
117  */
118 class FE_DL_EXPORT BaseType : public Counted, public ClassSafe<GlobalHolder>
119 {
120  public:
121  class FE_DL_PUBLIC FE_CORE_PORT Info : public Counted
122  {
123  public:
124  typedef enum
125  {
126  e_binary,
127  e_ascii
128  } t_serialMode;
129  Info(void)
130  {
131 #if FE_COUNTED_STORE_TRACKER
132  setName("BaseType::Info");
133 #endif
134 #if FE_CODEGEN<=FE_DEBUG && FE_OS==FE_LINUX && FE_HEAP_CHECKABLE
135  U8 current_stack;
136  if((void*)this>(void*)&current_stack)
137  feX("fe::BaseType::Info::Info",
138  "Info object not on stack");
139 #endif
140  suppressReport();
141  }
142  virtual ~Info(void) {}
143  virtual bool getConstruct(void) { return false; }
144  virtual void construct(void *instance) {}
145  virtual void destruct(void *instance) {}
146  virtual BWORD copy(void *instance,const void* source)
147  {
148  if(iosize()==c_implicit)
149  return FALSE;
150  memcpy(instance,source,iosize());
151  return TRUE;
152  }
153  virtual IWORD output( std::ostream &ostrm, void *instance,
154  t_serialMode mode) = 0;
155  virtual void input( std::istream &istrm, void *instance,
156  t_serialMode mode) = 0;
157  virtual String print(void *instance) { return String(); }
158  virtual IWORD iosize(void) { return c_implicit; }
159  virtual FE_UWORD alignment(void) { return 0; }
160 
161  /** implicit variable size. avoid. mainly for internal use. */
162  static FE_DL_PUBLIC const IWORD c_implicit;
163  /** explicit variable size. network byte order 32 bit unsigned
164  integer should follow */
165  static FE_DL_PUBLIC const IWORD c_explicit;
166  static FE_DL_PUBLIC const IWORD c_noascii;
167  static FE_DL_PUBLIC const IWORD c_ascii;
168 
169 #if FE_COUNTED_STORE_TRACKER
170  const String verboseName(void) const
171  { return "BaseType::Info "+name(); }
172 #endif
173  };
174  public:
175  BaseType(void);
176 virtual ~BaseType(void);
177 virtual FE_UWORD size(void) const;
178 virtual void assign(void *lvalue, void *rvalue) =0;
179 virtual bool equiv(void *a_a, void *a_b) =0;
180 virtual void setInfo(const sp<Info> &spInfo);
181 virtual void setInfo(Info *pInfo);
182 virtual sp<Info> getInfo(void);
183 
184 virtual bool getConstruct(void) const;
185 virtual void construct(void *instance);
186 virtual void destruct(void *instance);
187 virtual BWORD copy(void *instance,const void* source);
188 virtual TypeInfo &typeinfo(void);
189 virtual sp<BaseTypeVector> createVector(void) =0;
190 
191 
192 #if FE_COUNTED_STORE_TRACKER || FE_TYPE_STORE_NAME
193 const String verboseName(void) const { return "Type<"+name()+">"; }
194 #endif
195 
196 #if FE_TYPE_STORE_NAME
197 virtual
198 const String& name(void) const { return m_storedName; }
199  void setName(const String& a_name)
200  { m_storedName=a_name; }
201  private:
202  String m_storedName;
203 #endif
204 
205  protected:
206  FE_UWORD m_size;
207  sp<Info> m_spInfo;
208  TypeInfo m_typeInfo;
209 };
210 
211 
212 template <class T>
213 class FE_DL_EXPORT TypeInfoInitialized : public BaseType::Info
214 {
215  public:
216  TypeInfoInitialized(void)
217  {
218 #if FE_COUNTED_STORE_TRACKER
219  setName(FE_TYPESTRING(T));
220 #endif
221  }
222 virtual ~TypeInfoInitialized(void) { }
223 virtual bool getConstruct(void) { return true; }
224 virtual void construct(void *instance) { *((T *)instance)=T(0); }
225 virtual IWORD output( std::ostream &ostrm, void *instance,
226  t_serialMode mode)
227  {
228  if(mode == e_binary) { return 0; }
229  else { return c_noascii; }
230  }
231 virtual void input( std::istream &istrm, void *instance,
232  t_serialMode mode) { }
233 virtual IWORD iosize(void) { return sizeof(T); }
234 };
235 
236 template <class T>
237 class FE_DL_EXPORT TypeInfoConstructable : public BaseType::Info
238 {
239  public:
240  TypeInfoConstructable(void)
241  {
242 #if FE_COUNTED_STORE_TRACKER
243  setName(FE_TYPESTRING(T));
244 #endif
245  }
246 virtual ~TypeInfoConstructable(void) { }
247 virtual bool getConstruct(void) { return true; }
248 virtual void construct(void *instance) { new(instance)T; }
249 virtual void destruct(void *instance) { ((T *)instance)->~T(); }
250 virtual IWORD output( std::ostream &ostrm, void *instance,
251  t_serialMode mode)
252  {
253  if(mode == e_binary) { return 0; }
254  else { return c_noascii; }
255  }
256 virtual void input( std::istream &istrm, void *instance,
257  t_serialMode mode) { }
258 };
259 
260 template <class T>
261 class FE_DL_EXPORT TypeInfoMemcpyIO : public BaseType::Info
262 {
263  public:
264 virtual IWORD output(std::ostream &ostrm, void *instance, t_serialMode mode);
265 virtual void input(std::istream &istrm, void *instance, t_serialMode mode);
266 virtual IWORD iosize(void);
267 };
268 
269 #if 0
270 template <class T>
271 class FE_DL_EXPORT TypeVector : public BaseTypeVector
272 {
273  public:
274  TypeVector(void)
275  {
276  m_base = NULL;
277  m_vector = NULL;
278  m_size = sizeof(T);
279  }
280 virtual ~TypeVector(void)
281  {
282  if(m_vector)
283  {
284  deallocate(m_vector);
285  }
286  }
287 
288 virtual void resize(unsigned int a_size)
289  {
290  if(m_vector && a_size == 0)
291  {
292  deallocate(m_vector);
293  m_vector = NULL;
294  m_base = NULL;
295  return;
296  }
297  if(!m_vector)
298  {
299  m_vector = (T *)allocate(a_size*m_size);
300  }
301  else
302  {
303  m_vector = (T *)reallocate((void *)m_vector, a_size*m_size);
304  }
305  m_base = m_vector;
306  }
307 
308 virtual void *raw_at(unsigned int a_index)
309  {
310  return (void *)&m_vector[a_index];
311  }
312 
313  T &at(unsigned int a_index)
314  {
315  return m_vector[a_index];
316  }
317 
318  private:
319  T *m_vector;
320 };
321 #endif
322 
323 
324 #if 1
325 template <class T>
326 class FE_DL_EXPORT TypeVector:
327  public BaseTypeVector,
328  public CastableAs< TypeVector<int> >
329 {
330  public:
331  TypeVector(void)
332  {
333  m_base = NULL;
334  m_size = sizeof(T);
335  //TODO: 1000 seems grossly arbitrary
336  m_vector.reserve(1000);
337  }
338 virtual ~TypeVector(void)
339  {
340 #if FE_COUNTED_STORE_TRACKER
341  if(m_base)
342  {
343  deregisterRegion(m_base);
344  }
345 #endif
346  }
347 
348 virtual void resize(unsigned int a_size)
349  {
350 #if FE_COUNTED_STORE_TRACKER
351  if(m_base)
352  {
353  deregisterRegion(m_base);
354  }
355 #endif
356 
357  m_vector.resize(a_size);
358  if(a_size > 0)
359  {
360  m_base = (void *)&(m_vector[0]);
361  }
362 
363 #if FE_COUNTED_STORE_TRACKER
364  registerRegion(m_base,a_size*m_size);
365 #endif
366  }
367 
368 virtual void *raw_at(unsigned int a_index)
369  {
370  return (void *)&m_vector[a_index];
371  }
372 
373  T &at(unsigned int a_index)
374  {
375  return m_vector[a_index];
376  }
377 
378 #if FE_COUNTED_STORE_TRACKER
379 const String verboseName(void) const { return "TypeVector "+name(); }
380 #endif
381 
382  private:
383  Array<T> m_vector;
384 };
385 
386 
387 // work around stupid STL decision to specialize std::vector<bool>
388 template <>
389 class FE_DL_EXPORT TypeVector<bool> : public BaseTypeVector
390 {
391  public:
392  TypeVector(void)
393  {
394  m_base = NULL;
395  m_vector = NULL;
396  m_size = sizeof(bool);
397  }
398 virtual ~TypeVector(void)
399  {
400  if(m_vector)
401  {
402  deallocate(m_vector);
403  }
404  }
405 
406 virtual void resize(unsigned int a_size)
407  {
408  if(m_vector && a_size == 0)
409  {
410  deallocate(m_vector);
411  m_vector = NULL;
412  m_base = NULL;
413  return;
414  }
415  if(!m_vector)
416  {
417  m_vector = (bool *)allocate(a_size*m_size);
418  }
419  else
420  {
421  m_vector = (bool *)reallocate((void *)m_vector, a_size*m_size);
422  }
423  m_base = m_vector;
424  }
425 
426 virtual void *raw_at(unsigned int a_index)
427  {
428  return (void *)&m_vector[a_index];
429  }
430 
431  bool &at(unsigned int a_index)
432  {
433  return m_vector[a_index];
434  }
435 
436  private:
437  bool *m_vector;
438 };
439 #endif
440 
441 /** @brief A class to associate functionality with run time types.
442 
443  @ingroup core
444 
445  See BaseType for details.
446  */
447 template <class T>
448 class FE_DL_EXPORT Type : public BaseType
449 {
450  public:
451  Type(void);
452 virtual ~Type(void);
453 virtual void assign(void *lvalue, void *rvalue);
454 virtual bool equiv(void *a_a, void *a_b);
455 static Type<T>* create(void);
456 virtual sp<BaseTypeVector> createVector(void);
457 };
458 
459 template <class T>
461 {
462  sp< BaseTypeVector > spBTV(new TypeVector<T>);
463  return spBTV;
464 }
465 
466 template <>
468 {
469  sp< BaseTypeVector > spBTV(new BaseTypeVector());
470  return spBTV;
471 }
472 
473 
474 template <class T>
475 inline Type<T>::Type(void)
476 {
477  m_size=sizeof(T);
478  m_typeInfo.assign<T>();
479 #if FE_COUNTED_STORE_TRACKER || FE_TYPE_STORE_NAME
480  setName(m_typeInfo.ref().name());
481 #endif
482 }
483 
484 template <class T>
485 inline Type<T>::~Type(void)
486 {
487 }
488 
489 template <class T>
490 inline void Type<T>::assign(void *lvalue, void *rvalue)
491 { *(reinterpret_cast<T *>(lvalue)) = *(reinterpret_cast<T *>(rvalue)); }
492 
493 template <class T>
494 inline bool Type<T>::equiv(void *a_a, void *a_b)
495 {
496  return (*(reinterpret_cast<T *>(a_a)) == *(reinterpret_cast<T *>(a_b)));
497 }
498 
499 template <class T>
500 inline Type<T>* Type<T>::create(void)
501 {
502  Type<T>* pType=new Type<T>;
503  pType->registerRegion(pType,sizeof(Type<T>));
504 // feLog("Type< %s >::create %p %p %p %s\n",
505 // FE_TYPESTRING(T).c_str(),
506 // &create,pType,pType->typeinfo().ref().name(),
507 // pType->typeinfo().ref().name());
508  return pType;
509 }
510 
511 template<>
512 inline void Type<void>::assign(void *lvalue, void *rvalue)
513 { }
514 
515 template<>
516 inline bool Type<void>::equiv(void *a_a, void *a_b)
517 {
518  return true;
519 }
520 
521 template<>
522 inline Type<void>::Type(void)
523 { m_size=0; }
524 
525 inline FE_UWORD BaseType::size(void) const
526 {
527  SAFEGUARDCLASS;
528  return m_size;
529 }
530 
531 template <class T>
532 inline IWORD TypeInfoMemcpyIO<T>::output(std::ostream &ostrm, void *instance,
533  t_serialMode mode)
534 {
535  if(mode == e_binary)
536  {
537  ostrm.write((char *)instance, sizeof(T));
538  return sizeof(T);
539  }
540  return c_noascii;
541 }
542 
543 template <class T>
544 inline void TypeInfoMemcpyIO<T>::input(std::istream &ostrm, void *instance,
545  t_serialMode mode)
546 {
547  ostrm.read((char *)instance, sizeof(T));
548 }
549 
550 template <class T>
551 inline IWORD TypeInfoMemcpyIO<T>::iosize(void)
552 {
553  return sizeof(T);
554 }
555 
556 inline TypeInfo::TypeInfo(void)
557 {
558  m_pTypeInfo = &getTypeId<not_initialized>();
559  FEASSERT(m_pTypeInfo);
560 }
561 
562 inline TypeInfo::TypeInfo(const fe_type_info &other)
563 {
564  m_pTypeInfo = &other;
565  FEASSERT(m_pTypeInfo);
566 }
567 
568 inline TypeInfo::TypeInfo(const TypeInfo &other)
569 {
570  m_pTypeInfo = other.m_pTypeInfo;
571  FEASSERT(m_pTypeInfo);
572 }
573 
574 inline TypeInfo &TypeInfo::operator=(const TypeInfo &other)
575 {
576  if(this != &other)
577  {
578  m_pTypeInfo = other.m_pTypeInfo;
579  }
580  FEASSERT(m_pTypeInfo);
581  return *this;
582 }
583 
584 inline const fe_type_info &TypeInfo::ref(void) const
585 {
586  FEASSERT(m_pTypeInfo);
587  return *m_pTypeInfo;
588 }
589 
590 inline bool TypeInfo::isValid(void) const
591 {
592  return (bool)(ref() != getTypeId<not_initialized>());
593 }
594 
595 #if defined(GCC_HASCLASSVISIBILITY) || FE_RTTI_HOMEBREW == 1
596 inline bool TypeInfo::operator==(const TypeInfo &other) const
597 {
598  const char* n1=ref().name();
599  const char* n2=other.ref().name();
600  return n1==n2 || !strcmp(n1,n2);
601 }
602 
603 inline bool TypeInfo::operator!=(const TypeInfo &other) const
604 {
605  return !(*this==other);
606 }
607 
608 inline bool TypeInfo::operator<(const TypeInfo &other) const
609 {
610  const char* n1=ref().name();
611  const char* n2=other.ref().name();
612  return strcmp(n1,n2)<0;
613 }
614 
615 inline bool TypeInfo::operator>(const TypeInfo &other) const
616 {
617  const char* n1=ref().name();
618  const char* n2=other.ref().name();
619  return strcmp(n1,n2)>0;
620 }
621 
622 inline bool TypeInfo::operator>=(const TypeInfo &other) const
623 {
624  return !(*this<other);
625 }
626 
627 inline bool TypeInfo::operator<=(const TypeInfo &other) const
628 {
629  return !(*this>other);
630 }
631 #else
632 inline bool TypeInfo::operator==(const TypeInfo &other) const
633 {
634  return ref() == other.ref();
635 }
636 
637 inline bool TypeInfo::operator!=(const TypeInfo &other) const
638 {
639  return ref() != other.ref();
640 }
641 
642 inline bool TypeInfo::operator<(const TypeInfo &other) const
643 {
644  return ref().before(other.ref());
645 }
646 
647 inline bool TypeInfo::operator>(const TypeInfo &other) const
648 {
649  return other.ref().before(ref());
650 }
651 
652 inline bool TypeInfo::operator>=(const TypeInfo &other) const
653 {
654  return !(ref().before(other.ref()));
655 }
656 
657 inline bool TypeInfo::operator<=(const TypeInfo &other) const
658 {
659  return !(other.ref().before(ref()));
660 }
661 #endif
662 
663 struct eq_type_info
664 {
665  bool operator()(const TypeInfo &t1, const TypeInfo &t2) const
666  {
667  return t1 == t2;
668  }
669 };
670 
671 struct hash_type_info
672 {
673  FE_UWORD operator()(const TypeInfo &t) const
674  {
675  FE_UWORD hash = 0;
676  FE_UWORD len = strlen(t.ref().name());
677  for(FE_UWORD i = 0; i < len; i++)
678  { hash = (hash << 3) + t.ref().name()[i]; }
679  return hash;
680  }
681 };
682 
683 template<typename U>
684 class AutoHashMap< TypeInfo, U >:
685  public HashMap< TypeInfo, U, hash_type_info, eq_type_info > {};
686 
687 } /* namespace */
688 
689 #endif /* __core_Type_h__ */
Class level locking for thread safety.
Definition: Safe.h:201
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:448
A class to associate functionality with run time types.
Definition: Type.h:118
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:121
Wrapper for std::vector.
Definition: Array.h:21
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192