param_types.h
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:17k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  param_types.h
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #ifndef LEDA_PARAM_TYPE_H
  12. #define LEDA_PARAM_TYPE_H
  13. //----------------------------------------------------------------------------
  14. // Parameterized data types store copies of values of arbitrary types T
  15. // in a single data field of type void* (GenPtr). There are two cases
  16. // which have to be treated differently here.
  17. //
  18. // If T is a "big type" (sizeof(T) > sizeof(GenPtr)) we make a copy in the 
  19. // dynamic memory using the new operator and store a pointer to this copy. 
  20. // If T is a "small type" (sizeof(T) <= sizeof(GenPtr)) we avoid the 
  21. // overhead of an extra level of indirection by copying the value directly 
  22. // into the void* data field. This is done by using the "in-place" variant 
  23. // of the new operator. A good description of this feature can be found 
  24. // in  R.B. Murray: "C++ Strategies and Tactics" (chapter 9.5). We would
  25. // like to thank all people contributing to this solution by sending us
  26. // problem reports and helpful suggestions (see LEDA/ACKNOWLEDGEMENTS).
  27. //
  28. // Both cases are handled by the "Copy" function template defined in this file.
  29. // Similarly, the two cases (small or big type) have to be treated differently,
  30. // when creating ("Create"), destroying ("Clear"), and accessing ("Access") 
  31. // data of a parameterized type. Note that destruction of small types uses an
  32. // an explicit destructor call which is not supported by some compilers.
  33. //
  34. // More details on the implementation of parameterized data types in LEDA
  35. // will be given in the text book "LEDA: A Platform ..."  by K. Mehlhorn
  36. // and S. Naeher (to appear in the begining of 1996)
  37. //
  38. //----------------------------------------------------------------------------
  39. #if defined (__TEMPLATE_FUNCTIONS__)
  40. // Most c++ implementations provide an in-place new operator in <new.h>.
  41. // However, it is not always declared inline. So, for efficiency reasons,
  42. // we define our own (inline) version. It has been suggested to overload 
  43. // the new operator using a third dummy argument to avoid conflicts with
  44. // user defined variants, e.g  void* operator new(size_t, void*, int) 
  45. // Because we had not the time to test this with enough compilers and
  46. // do not know if there is really a problem here we did not include it
  47. // in the curent version. However, you can switch to this solution by
  48. // turning on the AVOID_CONFLICTS_WITH_NEW flag.
  49. //
  50. // For compilers not supporting explicit destructor calls or in-place new
  51. // we use the old method based on casting and assignment. Then 0 must be
  52. // legal value on the left side of assignments for all one-word types.
  53. #if defined(__INPLACE_NEW__)
  54. inline void Avoid_Unused_Warning(GenPtr) {}
  55. // work-around for a g++ bug:  cast the place operand to a T* pointer
  56. #if defined(AVOID_CONFLICTS_WITH_NEW)
  57. inline void* operator new(size_t, void* where, int) { return where; }
  58. #define COPY_INTO_WORD(T,x,p) Avoid_Unused_Warning(new((T*)&p,0) T(x))
  59. #define CONSTRUCT_WORD(T,p)   Avoid_Unused_Warning(new((T*)&p,0) T)
  60. #else
  61. inline void* operator new(size_t, void* where) { return where; }
  62. #define COPY_INTO_WORD(T,x,p) Avoid_Unused_Warning(new((T*)&p) T(x))
  63. #define CONSTRUCT_WORD(T,p)   Avoid_Unused_Warning(new((T*)&p) T)
  64. #endif
  65. #else
  66. #define COPY_INTO_WORD(T,x,p) *(T*)&p = x;
  67. #define CONSTRUCT_WORD(T,p)   { T x; COPY_INTO_WORD(T,x,p); }
  68. #endif
  69. #if defined(__EXPLICIT_DESTRUCTION__)
  70. #if !defined(__WATCOMC__)
  71. #define DESTROY_WORD(T,p)     p->T::~T();
  72. #else
  73. #define DESTROY_WORD(T,p)     p->~T();
  74. #endif
  75. #else
  76. inline void explicit_destruction(GenPtr) {}
  77. #define DESTROY_WORD(T,p)  explicit_destruction((T*)p)
  78. #endif
  79. //----------------------------------------------------------------------------
  80. // Function templates for Copy, Create, Clear, Convert, Access, etc. and 
  81. // default implementations of Print, Read, compare, and Hash. When using 
  82. // a compiler that does not support function templates (g++-2.5.8) these
  83. // functions have to be created for class types by a call of the LEDA_TYPE_
  84. // PARAMETER macro defined at end of this file. Most of the templates 
  85. // distinguish the two cases that the actual type has size greater than the 
  86. // size of a pointer or not, i.e., is a big or small type. Note that this 
  87. // does not cause any overhead at run time since the right case can be 
  88. // determined at compile time. 
  89. //----------------------------------------------------------------------------
  90. template<class T>
  91. inline GenPtr Copy(const T& x)
  92. { GenPtr p=0;
  93.   if (sizeof(T) <= sizeof(GenPtr)) COPY_INTO_WORD(T,x,p);
  94.   if (sizeof(T) >  sizeof(GenPtr)) p = new T(x);
  95.   return p;
  96.  }
  97. template <class T>
  98. inline GenPtr Create(const T*) 
  99. { GenPtr p=0;
  100.   if (sizeof(T) <= sizeof(GenPtr)) CONSTRUCT_WORD(T,p);
  101.   if (sizeof(T) >  sizeof(GenPtr)) p = new T;
  102.   return p;
  103.  }
  104. template <class T>
  105. inline void Clear(T& x) 
  106. { T* p = &x;
  107.   if (sizeof(T) <= sizeof(GenPtr)) DESTROY_WORD(T,p);
  108.   if (sizeof(T) >  sizeof(GenPtr)) delete p;
  109. }
  110. template <class T>
  111. inline GenPtr Convert(const T& x) 
  112. { GenPtr p=0;
  113.   if (sizeof(T) == sizeof(GenPtr)) p = *(GenPtr*)&x;
  114.   if (sizeof(T) <  sizeof(GenPtr)) *(T*)&p = x;
  115.   if (sizeof(T) >  sizeof(GenPtr)) p = (GenPtr)&x;
  116.   return p;
  117.  }
  118. template <class T>
  119. inline T& Access(const T*, const GenPtr& p) 
  120. { if (sizeof(T) <= sizeof(GenPtr))
  121.      return *(T*)&p;
  122.   else
  123.      return *(T*)p; 
  124.  }
  125. template <class T> 
  126. inline int   Int_Type(const T*)  { return 0; }
  127. template <class T> 
  128. inline char* Type_Name(const T*) { return "unknown"; }
  129. //---------------------------------------------------------------------------
  130. // default definitions for Print and Read
  131. //---------------------------------------------------------------------------
  132. template <class T> 
  133. inline void Print(const T& x, ostream& out) 
  134. { if (sizeof(T) <= sizeof(GenPtr)) out << *(GenPtr*)&x;
  135.   if (sizeof(T) >  sizeof(GenPtr)) out << "(object at " << GenPtr(&x) << ")";
  136.  }
  137. template <class T>
  138. inline void Read(T&, istream&) { error_handler(1,"Read undefined"); }
  139. //---------------------------------------------------------------------------
  140. // default definitions for compare and hash
  141. //---------------------------------------------------------------------------
  142. template <class T>
  143. inline int compare(const T& x, const T& y)  
  144. { if (sizeof(T) > sizeof(GenPtr)) error_handler(1,"compare undefined");  
  145.   return *(long*)&x - *(long*)&y;
  146.  }
  147. template <class T>
  148. inline int Hash(const T& x)
  149. { if (sizeof(T) > sizeof(GenPtr)) error_handler(1,"Hash undefined");
  150.   return *(int*)&x;
  151.  }
  152. #else
  153. //---------------------------------------------------------------------------
  154. // Without function templates we have to provide functions for all
  155. // pointer types (GenPtr versions).
  156. //---------------------------------------------------------------------------
  157. inline GenPtr  Copy(const GenPtr& x)                 { return x; }
  158. inline GenPtr  Create(GenPtr)                        { return 0; }
  159. inline void    Clear(GenPtr)                         {}
  160. inline GenPtr  Convert(GenPtr x)                     { return x; }
  161. inline GenPtr& Access(const GenPtr, const GenPtr& p) { return *(GenPtr*)&p; }
  162. inline int   Int_Type(GenPtr)   { return 0; }
  163. inline char* Type_Name(GenPtr)  { return "unknown"; }
  164. inline int compare(const GenPtr& x, const GenPtr& y) { return long(x)-long(y);}
  165. inline int Hash(const GenPtr& x)  { return *(int*)&x; }
  166. inline void Print(const GenPtr& x, ostream& out) { out << x; }
  167. inline void Read(GenPtr, istream&) { }
  168. #endif
  169. //----------------------------------------------------------------------------
  170. // Specializations for some built-in types (to be extended as needed) for
  171. // compilers not supporting function templates at all or having particular 
  172. // problems with function templates (watcomc, lucid)
  173. //----------------------------------------------------------------------------
  174. #if !defined(__TEMPLATE_FUNCTIONS__) || defined(__WATCOMC__) || defined(__lucid) || defined(__GNUC__)
  175. inline GenPtr Copy(const char& x)  { GenPtr p; *(char*)&p = x;  return p; }
  176. inline GenPtr Copy(const short& x) { GenPtr p; *(short*)&p = x; return p; }
  177. inline GenPtr Copy(const int& x)   { GenPtr p; *(int*)&p = x;   return p; }
  178. inline GenPtr Copy(const long& x)  { GenPtr p; *(long*)&p = x;  return p; }
  179. inline GenPtr Copy(const float& x) { GenPtr p; *(float*)&p = x; return p; }
  180.  
  181. inline GenPtr Convert(const char& x)  { return Copy(x); }
  182. inline GenPtr Convert(const short& x) { return Copy(x); }
  183. inline GenPtr Convert(const int& x)   { return Copy(x); }
  184. inline GenPtr Convert(const long& x)  { return Copy(x); }
  185. inline GenPtr Convert(const float& x) { return Copy(x); }
  186.  
  187. inline GenPtr Create(const char*)  { return 0; }
  188. inline GenPtr Create(const short*) { return 0; }
  189. inline GenPtr Create(const int*)   { return 0; }
  190. inline GenPtr Create(const long*)  { return 0; }
  191. inline GenPtr Create(const float*) { return 0; }
  192.  
  193. inline void   Clear(char&)  {}
  194. inline void   Clear(short&) {}
  195. inline void   Clear(int&)   {}
  196. inline void   Clear(long&)  {}
  197. inline void   Clear(float&) {}
  198.  
  199. inline char&  Access(const char*, const GenPtr& p) { return *(char*)&p;  }
  200. inline short& Access(const short*,const GenPtr& p) { return *(short*)&p; }
  201. inline int&   Access(const int*,  const GenPtr& p) { return *(int*)&p;   }
  202. inline long&  Access(const long*, const GenPtr& p) { return *(long*)&p;  }
  203. inline float& Access(const float*,const GenPtr& p) { return *(float*)&p; }
  204.  
  205. #endif
  206. //----------------------------------------------------------------------------
  207. // A "special" specialization for "double" using the LEDA memory management 
  208. // if sizeof(double) > sizeof(GenPtr). 
  209. //----------------------------------------------------------------------------
  210. inline GenPtr Copy(const double& x)
  211. { GenPtr p;
  212.   if (sizeof(double) > sizeof(GenPtr))
  213.     { p = allocate_bytes(sizeof(double));
  214.       *(double*)p = x; }
  215.   else 
  216.       *(double*)&p = x;
  217.   return p;
  218.  }
  219. inline GenPtr Create(const double*)
  220. { GenPtr p;
  221.   if (sizeof(double) > sizeof(GenPtr))
  222.     { p = allocate_bytes(sizeof(double));
  223.       *(double*)p = 0; }
  224.   else 
  225.       *(double*)&p = 0;
  226.   return p;
  227.  }
  228. inline void Clear(double& x) 
  229. { if (sizeof(double) > sizeof(GenPtr)) deallocate_bytes(&x,sizeof(double)); }
  230. inline GenPtr Convert(const double& x) 
  231. { return (sizeof(double) <= sizeof(GenPtr)) ? *(GenPtr*)&x : GenPtr(&x); }
  232. inline double& Access(const double*, const GenPtr& p) 
  233. { return (sizeof(double) <= sizeof(GenPtr)) ? *(double*)&p : *(double*)p; }
  234. //----------------------------------------------------------------------------
  235. // integer type or not ?
  236. //----------------------------------------------------------------------------
  237. inline int Int_Type(const int*)  { return 1; }
  238. inline int Int_Type(const long*) { return sizeof(long) == sizeof(int); }
  239. //----------------------------------------------------------------------------
  240. // id numbers
  241. //----------------------------------------------------------------------------
  242. inline unsigned long ID_Number(GenPtr x) { return (unsigned long)x; }
  243. inline unsigned long ID_Number(char   x) { return (unsigned long)x; }
  244. inline unsigned long ID_Number(short  x) { return (unsigned long)x; }
  245. inline unsigned long ID_Number(int    x) { return (unsigned long)x; }
  246. inline unsigned long ID_Number(long   x) { return (unsigned long)x; }
  247. //----------------------------------------------------------------------------
  248. // type names
  249. //----------------------------------------------------------------------------
  250. inline char* Type_Name(const char*  ) { return "char";   }
  251. inline char* Type_Name(const short* ) { return "short";  }
  252. inline char* Type_Name(const int*   ) { return "int";    }
  253. inline char* Type_Name(const long*  ) { return "long";   }
  254. inline char* Type_Name(const float* ) { return "float";  }
  255. inline char* Type_Name(const double*) { return "double"; }
  256. //----------------------------------------------------------------------------
  257. // pre-defined linear orders, I/O, and hash functions
  258. //----------------------------------------------------------------------------
  259. //----------------------------------------------------------------------------
  260. // compare
  261. //----------------------------------------------------------------------------
  262. inline int compare(const char& x, const char& y)
  263. { return int(x)-int(y); }
  264. inline int compare(const int& x, const int& y)
  265. { if (x < y)  return -1; 
  266.   else if (x > y)  return  1; 
  267.   else return 0;
  268. }
  269. inline int compare(const long& x, const long& y)
  270. { if (x < y)  return -1; 
  271.   else if (x > y)  return  1; 
  272.   else return 0;
  273. }
  274. inline int compare(const double& x, const double& y)
  275. { if (x < y)  return -1; 
  276.   else if (x > y)  return  1; 
  277.   else return 0;
  278. }
  279. inline int compare(const float& x, const float& y)
  280. { if (x < y)  return -1; 
  281.   else if (x > y)  return  1; 
  282.   else return 0;
  283. }
  284. #if defined(__BUILTIN_BOOL__)
  285. inline int compare(const bool& x, const bool& y) {return char(x)-char(y);}
  286. #endif
  287. //----------------------------------------------------------------------------
  288. // hashing
  289. //----------------------------------------------------------------------------
  290. inline int Hash(const char&   x) { return int(x); }
  291. inline int Hash(const short&  x) { return int(x); }
  292. inline int Hash(const int&    x) { return int(x); }
  293. inline int Hash(const long&   x) { return int(x); }
  294. inline int Hash(const float&  x) { return int(x); }
  295. inline int Hash(const double& x) { return int(x); }
  296. #if defined(__BUILTIN_BOOL__)
  297. inline int Hash(const bool& x) { return int(x); }
  298. #endif
  299. //----------------------------------------------------------------------------
  300. // output
  301. //----------------------------------------------------------------------------
  302. inline void Print(const char& x, ostream& out  ) { out << x; }
  303. inline void Print(const short& x, ostream& out ) { out << x; }
  304. inline void Print(const int& x, ostream& out   ) { out << x; }
  305. inline void Print(const long& x, ostream& out  ) { out << x; }
  306. inline void Print(const float& x, ostream& out ) { out << x; }
  307. inline void Print(const double& x, ostream& out) { out << x; }
  308. #if defined(__BUILTIN_BOOL__)
  309. inline void  Print(const bool& x, ostream& out) { out << (x ? "true":"false"); }
  310. #endif
  311. //----------------------------------------------------------------------------
  312. // input
  313. //----------------------------------------------------------------------------
  314. inline void Read(char& x,  istream& in) { in >> x; }
  315. inline void Read(short& x, istream& in) { in >> x; }
  316. inline void Read(int&  x,  istream& in) { in >> x; }
  317. inline void Read(long& x,  istream& in) { in >> x; }
  318. inline void Read(float& x, istream& in) { in >> x; }
  319. inline void Read(double& x,istream& in) { in >> x; }
  320. #if defined(__BUILTIN_BOOL__)
  321. inline void  Read(bool&,  istream&) {}
  322. #endif
  323. //----------------------------------------------------------------------------
  324. // some useful macros 
  325. // (used in data type templates)
  326. //----------------------------------------------------------------------------
  327. #if defined(__TEMPLATE_FUNCTIONS__) && !defined(__WATCOMC__)
  328. // this should work with all compilers, however ...
  329. #define LEDA_ACCESS(T,p)     Access((const T*)0,p)
  330. #define LEDA_COPY(T,x)       x=Copy(LEDA_ACCESS(T,x))
  331. #define LEDA_CREATE(T,x)     x=Create((const T*)0)
  332. #define LEDA_CLEAR(T,x)      Clear(LEDA_ACCESS(T,x))
  333. #define LEDA_INT_TYPE(T)     Int_Type((const T*)0)
  334. #define LEDA_TYPE_NAME(T)    Type_Name((const T*)0)
  335. #else
  336. #if !defined(__TEMPLATE_FUNCTIONS__)
  337. #define LEDA_ACCESS(T,x)   (T&)(Access((T*)0,x))
  338. #define LEDA_COPY(T,x)     x=Copy(LEDA_ACCESS(T,x))
  339. #define LEDA_CREATE(T,x)   { T y; x=Copy(y); }
  340. #define LEDA_CLEAR(T,x)    Clear(LEDA_ACCESS(T,x))
  341. #define LEDA_INT_TYPE(T)   Int_Type((T*)0)
  342. #define LEDA_TYPE_NAME(T)  Type_Name((T*)0)
  343. #else
  344. // __WATCOMC__
  345. #define LEDA_ACCESS(T,p)   Access((const T*)0,(const GenPtr&)p)
  346. #define LEDA_COPY(T,x)     x=Copy((const T&)LEDA_ACCESS(T,x))
  347. #define LEDA_CREATE(T,x)   x=Create((const T*)0)
  348. #define LEDA_CLEAR(T,x)    Clear(LEDA_ACCESS(T,x))
  349. #define LEDA_INT_TYPE(T)   Int_Type((const T*)0)
  350. #define LEDA_TYPE_NAME(T)  Type_Name((const T*)0)
  351. #endif
  352. #endif
  353. #if defined(__ATTCFRONT__)
  354. #undef  LEDA_CREATE
  355. #define LEDA_CREATE(T,x)   { T y; x=Copy(y); }
  356. #endif
  357. #define LEDA_COMPARE(T,x,y)  compare(LEDA_ACCESS(T,x),LEDA_ACCESS(T,y))
  358. #define LEDA_HASH(T,x)       Hash(LEDA_ACCESS(T,x))
  359. #define LEDA_PRINT(T,x,out)  Print(LEDA_ACCESS(T,x),(ostream&)out)
  360. #define LEDA_READ(T,x,in)    Read(LEDA_ACCESS(T,x),(istream&)in)
  361.  
  362. //----------------------------------------------------------------------------
  363. // LEDA_TYPE_PARAMETER MACRO
  364. //
  365. // has to be called for any "big type" T before using T as an actual type 
  366. // argument in parameterized data types if function templates cannot be used.
  367. //----------------------------------------------------------------------------
  368.  
  369. #define LEDA_TYPE_PARAMETER(T)
  370. inline GenPtr Copy(const T& x)     { return new T(x); }
  371. inline GenPtr Create(const T*)     { return new T; }
  372. inline void   Clear(T& x)          { delete &x; }
  373. inline GenPtr Convert(const T& x)  { return (GenPtr)&x; }
  374. inline T&     Access(const T*, const GenPtr& p)  { return *(T*)p; }
  375. inline char*  Type_Name(const T*)  { return STRINGIZE(T); }
  376.  
  377. #endif