Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

286 lines
7.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: stlstream.h
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // stlstream.h: Stream STL template classes.
  12. //
  13. // Templates in this file typically generate functions which take a
  14. // stream reference as an argument, along with a const reference to
  15. // the thing to be streamed; it returns a reference to the stream.
  16. //
  17. // The reason that the stream parameter must be included in the
  18. // template is generate a function which returns the correct stream type.
  19. // If the stream type were not a templated argument, then the
  20. // template would be forced to return a single immutable type, such
  21. // as "ostream". This would cause cascaded stream insertion operators
  22. // to fail to compile, since type errors would occur in the middle of the
  23. // sequence. In the following example, assume that there is a special
  24. // insertion operator defined between class MYSTREAM and class Y:
  25. //
  26. // MYSTREAM myst;
  27. // extern MYSTREAM & operator << ( MYSTREAM & m, const Y & y );
  28. // X x;
  29. // Y y;
  30. //
  31. // myst << x // Template function generated and called
  32. // << y; // ERROR: return value of template function
  33. // // incorrect for special operator above.
  34. //
  35. #ifndef _STLSTREAM_H_
  36. #define _STLSTREAM_H_
  37. #include <iostream> // C++ RTL/STL Streams inclusion
  38. #include <fstream>
  39. #include "mscver.h" // Version-dependent stuff
  40. #include "zstr.h" // ZSTR handling
  41. #include "mdvect.h" // Multi-dimensional vector handling
  42. // Delimiters used in parameter files
  43. #define CH_EOS ((char)0) // End of string
  44. #define CH_DELM_OPEN ((char)'(') // Start of value group
  45. #define CH_DELM_CLOSE ((char)')') // End of value group
  46. #define CH_BLOCK_OPEN ((char)'{') // Start of value block
  47. #define CH_BLOCK_CLOSE ((char)'}') // End of value block
  48. #define CH_INDEX_OPEN ((char)'[') // Name index start
  49. #define CH_INDEX_CLOSE ((char)']') // Name index end
  50. #define CH_PREAMBLE ((char)':') // Delmiter for array size
  51. #define CH_FILL ((char)' ') // Fill character
  52. #define CH_SEP ((char)',') // Value group separator
  53. #define CH_DELM_STR ((char)'\"')
  54. #define CH_META ((char)'\\')
  55. #define CH_DELM_ENTRY ((char)';')
  56. #define CH_EQ ((char)'=')
  57. #define CH_NAME_SEP ((char)'.')
  58. //////////////////////////////////////////////////////////////////////////////////
  59. // Read and write STL pairs from or to a stream
  60. //////////////////////////////////////////////////////////////////////////////////
  61. template<class _OS, class _First, class _Second> inline
  62. _OS & operator << (_OS & os, const pair<_First,_Second> & pr)
  63. {
  64. os << CH_DELM_OPEN;
  65. os << pr.first;
  66. os << pr.second;
  67. os << CH_DELM_CLOSE;
  68. return os;
  69. }
  70. template<class _IS, class _First, class _Second> inline
  71. _IS & operator >> (_IS & is, pair<_First,_Second> & pr)
  72. {
  73. char ch;
  74. is >> ch;
  75. if (ch != CH_DELM_OPEN)
  76. _THROW1(runtime_error("invalid block: pair >> (1)"));
  77. is >> pr.first;
  78. is >> pr.second;
  79. is >> ch;
  80. if (ch != CH_DELM_CLOSE)
  81. _THROW1(runtime_error("invalid block: pair >> (2)"));
  82. return is;
  83. }
  84. //////////////////////////////////////////////////////////////////////////////////
  85. // Read and write STL vectors from or to a stream
  86. //////////////////////////////////////////////////////////////////////////////////
  87. template<class _OS, class _T> inline
  88. _OS & operator << (_OS & os, const vector<_T>& vt )
  89. {
  90. os << CH_DELM_OPEN;
  91. os << (UINT) vt.size();
  92. os << CH_PREAMBLE;
  93. for ( size_t i = 0; i < vt.size(); )
  94. {
  95. os << vt[i];
  96. if ( ++i != vt.size() )
  97. os << ',' ;
  98. }
  99. os << CH_DELM_CLOSE;
  100. return os;
  101. }
  102. template<class _IS, class _T> inline
  103. _IS & operator >> (_IS & is, vector<_T>& vt )
  104. {
  105. char ch;
  106. is >> ch;
  107. if (ch != CH_DELM_OPEN)
  108. _THROW1(runtime_error("invalid block: vector>> (1)"));
  109. size_t l;
  110. is >> l;
  111. is >> ch;
  112. if (ch != CH_PREAMBLE)
  113. _THROW1(runtime_error("invalid block: vector>> (2)"));
  114. vt.resize(l);
  115. for ( size_t i = 0 ; i < l; )
  116. {
  117. _T it;
  118. is >> it;
  119. vt[i] = it;
  120. if ( ++i < l )
  121. {
  122. is >> ch;
  123. if (ch != CH_SEP)
  124. break;
  125. }
  126. }
  127. if ( i != l )
  128. _THROW1(runtime_error("invalid block: vector>> (3)"));
  129. is >> ch;
  130. if (ch != CH_DELM_CLOSE)
  131. _THROW1(runtime_error("invalid block: vector>> (4)"));
  132. return is;
  133. }
  134. //////////////////////////////////////////////////////////////////////////////////
  135. // Read and write STL valarrays from or to a stream
  136. //////////////////////////////////////////////////////////////////////////////////
  137. template<class _OS, class _T> inline
  138. _OS & operator << ( _OS & os, const valarray<_T>& vt )
  139. {
  140. os << CH_DELM_OPEN;
  141. os << (UINT) vt.size();
  142. os << CH_PREAMBLE;
  143. for ( int i = 0;
  144. i < vt.size() ; )
  145. {
  146. os << vt[i];
  147. if ( ++i != vt.size() )
  148. os << ',' ;
  149. }
  150. os << CH_DELM_CLOSE;
  151. return os;
  152. }
  153. template<class _IS, class _T> inline
  154. _IS & operator >> (_IS & is, valarray<_T>& vt )
  155. {
  156. char ch;
  157. is >> ch;
  158. if (ch != CH_DELM_OPEN)
  159. _THROW1(runtime_error("invalid block: valarray >> (1)"));
  160. size_t l;
  161. is >> l;
  162. is >> ch;
  163. if (ch != CH_PREAMBLE)
  164. _THROW1(runtime_error("invalid block: valarray >> (2)"));
  165. vt.resize(l);
  166. for ( size_t i = 0 ; i < l; )
  167. {
  168. _T it;
  169. is >> it;
  170. vt[i] = it;
  171. if ( ++i < l )
  172. {
  173. is >> ch;
  174. if (ch != CH_SEP)
  175. break;
  176. }
  177. }
  178. if ( i != l )
  179. _THROW1(runtime_error("invalid block: valarray >> (3)"));
  180. is >> ch;
  181. if (ch != CH_DELM_CLOSE)
  182. _THROW1(runtime_error("invalid block: valarray >> (4)"));
  183. return is;
  184. }
  185. //////////////////////////////////////////////////////////////////////////////////
  186. // Read and write MDVSLICEs from or to a stream
  187. //////////////////////////////////////////////////////////////////////////////////
  188. template<class _OS> inline
  189. _OS & operator << (_OS & os, const MDVSLICE & mslice )
  190. {
  191. os << CH_DELM_OPEN;
  192. os << (UINT) mslice.start();
  193. os << mslice.size();
  194. os << mslice.stride();
  195. os << CH_DELM_CLOSE;
  196. return os;
  197. }
  198. template<class _IS> inline
  199. _IS & operator >> ( _IS & is, MDVSLICE & mslice )
  200. {
  201. char ch;
  202. is >> ch;
  203. if (ch != CH_DELM_OPEN)
  204. _THROW1(runtime_error("invalid block: slice >> (1)"));
  205. VIMD vimdLen;
  206. VIMD vimdStride;
  207. size_t lStart;
  208. is >> lStart;
  209. is >> vimdLen;
  210. is >> vimdStride;
  211. mslice = MDVSLICE( lStart, vimdLen, vimdStride );
  212. is >> ch;
  213. if (ch != CH_DELM_CLOSE)
  214. _THROW1(runtime_error("invalid block: slice >> (2)"));
  215. return is;
  216. }
  217. //////////////////////////////////////////////////////////////////////////////////
  218. // Format (pretty-print) MDVDENSEs using an Iterator.
  219. //
  220. // This is NOT the same as streaming out an MDVDENSE; it formats the array for
  221. // easy reading. Note that it requires an Iterator.
  222. //
  223. // MSRDEVBUG: This, too, should be templatized, but there's a bug in template
  224. // expansion using nested class names.
  225. //////////////////////////////////////////////////////////////////////////////////
  226. inline
  227. ostream & operator << ( ostream & os, TMDVDENSE<double>::Iterator & itmdv )
  228. {
  229. os << "\ndump of mdvect,\n\t\tslice = "
  230. << itmdv.Slice();
  231. if ( itmdv.Slice() != itmdv.Mdv().Slice() )
  232. {
  233. os << ",\n\t\toriginal slice = "
  234. << itmdv.Mdv().Slice();
  235. }
  236. if ( itmdv.BReorder() )
  237. {
  238. os << ",\n\t\treordered ";
  239. os << itmdv.VimdReorder();
  240. }
  241. os << '.';
  242. itmdv.Reset();
  243. for ( int ii = 0 ; itmdv.BNext() ; ii++ )
  244. {
  245. const VIMD & vimd = itmdv.Vitmd();
  246. cout << "\n\t[";
  247. for ( int i = 0 ; i < vimd.size(); i++ )
  248. {
  249. cout << vimd[i];
  250. if ( i + 1 < vimd.size() )
  251. cout << ",";
  252. }
  253. size_t indx = itmdv.Indx();
  254. const double & t = itmdv.Next();
  255. cout << "] ("
  256. << ii
  257. << '='
  258. << (UINT) indx
  259. << ") = "
  260. << t;
  261. }
  262. return os;
  263. }
  264. #endif // _STLSTREAM_H_