Listing G
#include <string>
#include <sstream>
#include <iostream>
 
 
 
 
/////////////////////////////////////
// the 'to_string' function
template< class type>
inline std::string to_string( const type & value)
{
    std::ostringstream streamOut;
    streamOut << value;
    return streamOut.str();
}
 
 
 
 
 
 
/////////////////////////////////////
// the 'str_stream' class
struct str_stream
{
    std::stringstream & underlying_stream() const
    { return m_streamOut; }
 
 
    operator std::string() const
    {
        return m_streamOut.str();
    }
private:
    mutable std::stringstream m_streamOut;
};
 
 
 
 
template< class type>
inline const str_stream & operator<< ( const str_stream & out, const type & value)
{
    out.underlying_stream() << value;
    return out;
}
 
 
 
 
#include <time.h>
#include <assert.h>
 
 
class CCpuClockTimespan
{
    enum
    { INVALID_VALUE = -1, };
 
 
public:
    CCpuClockTimespan()
        : m_clockStart( INVALID_VALUE),
          m_nUsedClockTicks( INVALID_VALUE)
    {}
    ~CCpuClockTimespan()
    {}
 
 
    void StartClock()
    {
        // the clock is already started !!!
        // stop it first !!!
       assert( m_clockStart == INVALID_VALUE);
        m_nUsedClockTicks = INVALID_VALUE;
        m_clockStart = clock();
    }
    void StopClock()
    {
        const clock_t clockStop = clock();
        // start the clock first !!!
        assert( m_clockStart != INVALID_VALUE);
        m_nUsedClockTicks = clockStop - m_clockStart;
        // after this, we can start it again !!!
        m_clockStart = INVALID_VALUE;
    }
    unsigned long GetUsedMilliseconds() const
    {
        const int MILLISECONDS_PER_SECOND = 1000;
        // the clock was never started,
        // or it's started, but it has not been stopped yet
        assert( m_nUsedClockTicks != INVALID_VALUE);
        double nSeconds =
            ( ( double)m_nUsedClockTicks) / CLOCKS_PER_SEC;
        const unsigned long nMilliseconds =
            ( unsigned long)( nSeconds * MILLISECONDS_PER_SECOND);
        return nMilliseconds;
    }
 
 
private:
    // when did we Start to measure
    // clock time?
    clock_t m_clockStart;
 
 
    // the used clock ticks, from Start to Stop
    int m_nUsedClockTicks;
};
 
 
 
 
 
 
inline void use_to_string()
{
    int nWordsCount = 48873;
    int nFilesCount = 17;
 
 
    // implicit conversion to string
    std::string str =
        "We parsed " + to_string( nFilesCount) + " files, and found " +
        to_string( nWordsCount) + " words.";
 
 
}
 
 
 
 
inline void use_str_stream()
{
    int nWordsCount = 48873;
    int nFilesCount = 17;
 
 
    // implicit conversion to string
    std::string str =
        str_stream() << "We parsed " << nFilesCount << " files, and found "
        << nWordsCount << " words.";
 
 
}
 
 
 
 
int main()
{
    const int TEST_TIMES = 1000000;
    CCpuClockTimespan span;
    int i;
 
 
    // make sure we use the CPU at its best
    std::cout << "starting test..." << std::endl;
    for ( i = 0; i < 10000; i++)
    {
        use_to_string();
        use_str_stream();
    }
    std::cout << "started" << std::endl;
 
 
 
 
 
 
    std::cout << "testing to_string: ";
    span.StartClock();
    for ( i = 0; i < TEST_TIMES; i++)
        use_to_string();
    span.StopClock();
    std::cout << " took " << span.GetUsedMilliseconds() << " ms." << std::endl;
 
 
 
 
 
 
    std::cout << "testing str_stream: ";
    span.StartClock();
    for ( i = 0; i < TEST_TIMES; i++)
        use_str_stream();
    span.StopClock();
    std::cout << " took " << span.GetUsedMilliseconds() << " ms." << std::endl;
 
 
 
 
 
 
    std::cin.get();
    return 0;
}