windows-nt/Source/XPSP1/NT/enduser/troubleshoot/bn/stlstream.h
2020-09-26 16:20:57 +08:00

287 lines
7.5 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: stlstream.h
//
//--------------------------------------------------------------------------
//
// stlstream.h: Stream STL template classes.
//
// Templates in this file typically generate functions which take a
// stream reference as an argument, along with a const reference to
// the thing to be streamed; it returns a reference to the stream.
//
// The reason that the stream parameter must be included in the
// template is generate a function which returns the correct stream type.
// If the stream type were not a templated argument, then the
// template would be forced to return a single immutable type, such
// as "ostream". This would cause cascaded stream insertion operators
// to fail to compile, since type errors would occur in the middle of the
// sequence. In the following example, assume that there is a special
// insertion operator defined between class MYSTREAM and class Y:
//
// MYSTREAM myst;
// extern MYSTREAM & operator << ( MYSTREAM & m, const Y & y );
// X x;
// Y y;
//
// myst << x // Template function generated and called
// << y; // ERROR: return value of template function
// // incorrect for special operator above.
//
#ifndef _STLSTREAM_H_
#define _STLSTREAM_H_
#include <iostream> // C++ RTL/STL Streams inclusion
#include <fstream>
#include "mscver.h" // Version-dependent stuff
#include "zstr.h" // ZSTR handling
#include "mdvect.h" // Multi-dimensional vector handling
// Delimiters used in parameter files
#define CH_EOS ((char)0) // End of string
#define CH_DELM_OPEN ((char)'(') // Start of value group
#define CH_DELM_CLOSE ((char)')') // End of value group
#define CH_BLOCK_OPEN ((char)'{') // Start of value block
#define CH_BLOCK_CLOSE ((char)'}') // End of value block
#define CH_INDEX_OPEN ((char)'[') // Name index start
#define CH_INDEX_CLOSE ((char)']') // Name index end
#define CH_PREAMBLE ((char)':') // Delmiter for array size
#define CH_FILL ((char)' ') // Fill character
#define CH_SEP ((char)',') // Value group separator
#define CH_DELM_STR ((char)'\"')
#define CH_META ((char)'\\')
#define CH_DELM_ENTRY ((char)';')
#define CH_EQ ((char)'=')
#define CH_NAME_SEP ((char)'.')
//////////////////////////////////////////////////////////////////////////////////
// Read and write STL pairs from or to a stream
//////////////////////////////////////////////////////////////////////////////////
template<class _OS, class _First, class _Second> inline
_OS & operator << (_OS & os, const pair<_First,_Second> & pr)
{
os << CH_DELM_OPEN;
os << pr.first;
os << pr.second;
os << CH_DELM_CLOSE;
return os;
}
template<class _IS, class _First, class _Second> inline
_IS & operator >> (_IS & is, pair<_First,_Second> & pr)
{
char ch;
is >> ch;
if (ch != CH_DELM_OPEN)
_THROW1(runtime_error("invalid block: pair >> (1)"));
is >> pr.first;
is >> pr.second;
is >> ch;
if (ch != CH_DELM_CLOSE)
_THROW1(runtime_error("invalid block: pair >> (2)"));
return is;
}
//////////////////////////////////////////////////////////////////////////////////
// Read and write STL vectors from or to a stream
//////////////////////////////////////////////////////////////////////////////////
template<class _OS, class _T> inline
_OS & operator << (_OS & os, const vector<_T>& vt )
{
os << CH_DELM_OPEN;
os << (UINT) vt.size();
os << CH_PREAMBLE;
for ( size_t i = 0; i < vt.size(); )
{
os << vt[i];
if ( ++i != vt.size() )
os << ',' ;
}
os << CH_DELM_CLOSE;
return os;
}
template<class _IS, class _T> inline
_IS & operator >> (_IS & is, vector<_T>& vt )
{
char ch;
is >> ch;
if (ch != CH_DELM_OPEN)
_THROW1(runtime_error("invalid block: vector>> (1)"));
size_t l;
is >> l;
is >> ch;
if (ch != CH_PREAMBLE)
_THROW1(runtime_error("invalid block: vector>> (2)"));
vt.resize(l);
for ( size_t i = 0 ; i < l; )
{
_T it;
is >> it;
vt[i] = it;
if ( ++i < l )
{
is >> ch;
if (ch != CH_SEP)
break;
}
}
if ( i != l )
_THROW1(runtime_error("invalid block: vector>> (3)"));
is >> ch;
if (ch != CH_DELM_CLOSE)
_THROW1(runtime_error("invalid block: vector>> (4)"));
return is;
}
//////////////////////////////////////////////////////////////////////////////////
// Read and write STL valarrays from or to a stream
//////////////////////////////////////////////////////////////////////////////////
template<class _OS, class _T> inline
_OS & operator << ( _OS & os, const valarray<_T>& vt )
{
os << CH_DELM_OPEN;
os << (UINT) vt.size();
os << CH_PREAMBLE;
for ( int i = 0;
i < vt.size() ; )
{
os << vt[i];
if ( ++i != vt.size() )
os << ',' ;
}
os << CH_DELM_CLOSE;
return os;
}
template<class _IS, class _T> inline
_IS & operator >> (_IS & is, valarray<_T>& vt )
{
char ch;
is >> ch;
if (ch != CH_DELM_OPEN)
_THROW1(runtime_error("invalid block: valarray >> (1)"));
size_t l;
is >> l;
is >> ch;
if (ch != CH_PREAMBLE)
_THROW1(runtime_error("invalid block: valarray >> (2)"));
vt.resize(l);
for ( size_t i = 0 ; i < l; )
{
_T it;
is >> it;
vt[i] = it;
if ( ++i < l )
{
is >> ch;
if (ch != CH_SEP)
break;
}
}
if ( i != l )
_THROW1(runtime_error("invalid block: valarray >> (3)"));
is >> ch;
if (ch != CH_DELM_CLOSE)
_THROW1(runtime_error("invalid block: valarray >> (4)"));
return is;
}
//////////////////////////////////////////////////////////////////////////////////
// Read and write MDVSLICEs from or to a stream
//////////////////////////////////////////////////////////////////////////////////
template<class _OS> inline
_OS & operator << (_OS & os, const MDVSLICE & mslice )
{
os << CH_DELM_OPEN;
os << (UINT) mslice.start();
os << mslice.size();
os << mslice.stride();
os << CH_DELM_CLOSE;
return os;
}
template<class _IS> inline
_IS & operator >> ( _IS & is, MDVSLICE & mslice )
{
char ch;
is >> ch;
if (ch != CH_DELM_OPEN)
_THROW1(runtime_error("invalid block: slice >> (1)"));
VIMD vimdLen;
VIMD vimdStride;
size_t lStart;
is >> lStart;
is >> vimdLen;
is >> vimdStride;
mslice = MDVSLICE( lStart, vimdLen, vimdStride );
is >> ch;
if (ch != CH_DELM_CLOSE)
_THROW1(runtime_error("invalid block: slice >> (2)"));
return is;
}
//////////////////////////////////////////////////////////////////////////////////
// Format (pretty-print) MDVDENSEs using an Iterator.
//
// This is NOT the same as streaming out an MDVDENSE; it formats the array for
// easy reading. Note that it requires an Iterator.
//
// MSRDEVBUG: This, too, should be templatized, but there's a bug in template
// expansion using nested class names.
//////////////////////////////////////////////////////////////////////////////////
inline
ostream & operator << ( ostream & os, TMDVDENSE<double>::Iterator & itmdv )
{
os << "\ndump of mdvect,\n\t\tslice = "
<< itmdv.Slice();
if ( itmdv.Slice() != itmdv.Mdv().Slice() )
{
os << ",\n\t\toriginal slice = "
<< itmdv.Mdv().Slice();
}
if ( itmdv.BReorder() )
{
os << ",\n\t\treordered ";
os << itmdv.VimdReorder();
}
os << '.';
itmdv.Reset();
for ( int ii = 0 ; itmdv.BNext() ; ii++ )
{
const VIMD & vimd = itmdv.Vitmd();
cout << "\n\t[";
for ( int i = 0 ; i < vimd.size(); i++ )
{
cout << vimd[i];
if ( i + 1 < vimd.size() )
cout << ",";
}
size_t indx = itmdv.Indx();
const double & t = itmdv.Next();
cout << "] ("
<< ii
<< '='
<< (UINT) indx
<< ") = "
<< t;
}
return os;
}
#endif // _STLSTREAM_H_