<Release> Simple C/C++ Perfometer: Copying Files (Versions 5.x)

9 views
Skip to first unread message

Alex Vinokur

unread,
Nov 19, 2013, 6:48:02 AM11/19/13
to pe...@googlegroups.com
// ===========================================================================
//
//  C/C++ Program Performance Measurement
    #define PROGRAM_NAME     "Simple C/C++ Perfometer : Copying files"
    #define PROGRAM_VERSION  "Version F2F-5.0"
//
//  -------------------------------------
//
//  Copyright (C) 2002-2013 Alex Vinokur
//
//  --------------------------------------------------------------------------
//
//  This software is provided 'as-is', without any express or implied
//  warranty.  In no event will the author be held liable for any damages
//  arising from the use of this software.
//
//  Permission is granted to anyone to use this software for any purpose,
//  including commercial applications, and to alter it and redistribute it
//  freely, subject to the following restrictions:
//
//  1. The origin of this software must not be misrepresented; you must not
//     claim that you wrote the original software. If you use this software
//     in a product, an acknowledgment in the product documentation would be
//     appreciated but is not required.
//  2. Altered source versions must be plainly marked as such, and must not be
//     misrepresented as being the original software.
//  3. This notice may not be removed or altered from any source distribution.
//
//     Alex Vinokur
//     
//  --------------------------------------------------------------------------
// 
//  email:alex DOT vinokur AT gmail DOT com
//
// ===========================================================================



// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
//    Testsuites
//    ----------
//    C_01      : C-Functions getc() and putc()
//    C_02      : C-Functions fgetc() and fputc()
//    C_03      : C-Functions fread() and fwrite() - with const size buffer
//    C_04      : C-Functions fread() and fwrite() - with max size buffer
//    C_UNIX_01 : UNIX system call mmap with write
//    C_UNIX_02 : UNIX system call mmap with memcpy
//    CPP_01    : istream::operator>> and ostream::operator<<
//    CPP_02    : streambuf::sbumpc() and streambuf::sputc()
//    CPP_03    : streambuf::sbumpc() and ostream::operator<<
//    CPP_04    : std::ifstream::rdbuf() and ostream::operator<<
//    CPP_05    : istream::read() and ostream::write() - with const size buffer
//    CPP_06    : istream::read() and ostream::write(), std::std::ostringstream, ostream::operator<< - with const buffer
//    CPP_07    : istream::readsome() and ostream::write() - with const size buffer
//    CPP_08    : istream::read() and ostream::write() - with max size buffer
//    CPP_09    : std::std::getline, std::std::ostringstream, ostream::operator<<
//    CPP_10    : std::std::getline, std::std::string, ostream::operator<<
//    CPP_11    : istream::std::getline, std::std::ostringstream, ostream::operator<<
//    CPP_12    : istream::get(char) and ostream::put
//    CPP_13    : istream::get(char)
//    CPP_14    : istream::get(char*, std::streamsize) , ostream::operator<< - with const size buffer
//    CPP_15    : istream::get(streambuf&)  and std::streambuf, ostream::operator<<
//    CPP_16    : std::std::istream_iterator, std::std::ostream_iterator and std::std::copy
//    CPP_17    : std::std::istream_iterator, std::std::string
//    CPP_18    : std::std::istreambuf_iterator, std::std::ostreambuf_iterator and std::std::copy
//    CPP_19    : std::std::istreambuf_iterator, std::std::ostreambuf_iterator and std::transform
//    CPP_20    : std::std::istreambuf_iterator and std::std::string
//    CPP_21    : std::std::vector and std::std::copy
//    CPP_22    : std::std::vector and push_back()
//    CPP_23    : std::std::vector and istream::read()
//    CPP_24    : std::std::string and istream::read()
//
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



// --------------------------------------

// ==============
#include <cstdio>
#include <cerrno>
#include <ctime>
#include <climits>
#include <cassert>
#include <cstring>
#include <string>
#include <vector>
#include <limits>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <iterator>
#include <algorithm>
#ifdef __unix
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#endif


// --------------------------------------
// #define ONLY_MMAP_TEST 1

#define  MAX_VALUE(x,y)  ((x) > (y) ? (x) : (y))

#define  ASSERT(x)       if (!(x)) \
{ \
assert(x); \
std::cerr << "[" \
     << __FILE__ \
     << ", " \
     << __LINE__  \
     << "] assert() not working" \
     << std::endl;  \
     abort(); \
}

#define ROWS_IN_INPUT_FILE 15

// ========================================
// ====== Part-0: Function Prototypes 
// ========================================

static std::string getCompilationMachineName ();
static std::string getRunMachineName (bool i_detailedInfo);
static std::string get_compiler_info();
static void show_env_info();

static std::size_t getFileSize (const std::string& i_fileName, const bool i_mode);
static std::size_t getFileSizeViaSeekgTellg (const std::string& i_fileName, const bool i_mode);
static std::string file2string (std::ifstream& io_fin, std::size_t i_filesize);
static std::string file2string (const char * const i_fileName, const bool i_mode = false);

static void auxCheckAssertOut (const char * const i_fileName, const std::size_t i_lineNo);
static void auxOpenFpOut (const char * const i_fileName, FILE*& o_fp, const char * const i_mode, const std::size_t i_lineNo);
static void auxCloseFpOut (const char * const i_fileName, FILE*& o_fp, const std::size_t i_lineNo);
#ifdef __unix
static void auxOpenFdOut (const char * const i_fileName, int&  o_fdOut, const int i_fdIn, const std::size_t i_lineNo);
static void auxCloseFdOut (const char * const i_fileName, int& fd_o, const std::size_t i_lineNo);
#endif
static void auxOpenFsOut (const char * const i_fileName, std::ofstream& fs_o, const std::size_t i_lineNo, const bool i_mode = false);
static void auxCloseFsOut (const char * const i_fileName, std::ofstream& fs_o, const std::size_t i_lineNo);
static void openFpOut (const std::size_t i_lineNo);
static void closeFpOut (const std::size_t i_lineNo);
static void openFsOut (const std::size_t i_lineNo);
static void close_s_fsOut (const std::size_t i_lineNo);
#ifdef __unix
static void openFdOut (const std::size_t i_lineNo);
static void closeFdOut (const std::size_t i_lineNo);
#endif
static void fillInputFile (std::size_t total_full_rows = ROWS_IN_INPUT_FILE);

static void C_01__functions_getc_putc ();
static void C_02__functions_fgetc_fputc ();
static void C_03__functions_fread_fwrite__const_buf ();
static void C_04__functions_fread_fwrite__max_buf ();
static void C_UNIX_01__mmap_write ();
static void C_UNIX_02__mmap_memcpy ();
static void CPP_01__operators_in_out ();
static void CPP_02__methods_sbumpc_sputc ();
static void CPP_03__method_sbumpc__op_out ();
static void CPP_04__method_rdbuf__op_out ();
static void CPP_05__methods_cpp_read_write__const_buf ();
static void CPP_06__methods_cpp_read_write_oss__const_buf ();
static void CPP_07__methods_cpp_readsome_write__const_buf ();
static void CPP_08__methods_cpp_read_write__max_buf ();
static void CPP_09__function_getline__ostringstream ();
static void CPP_10__function_getline__string ();
static void CPP_11__method_ifstream_getline ();
static void CPP_12__methods_ifstream_get_put ();
static void CPP_13__method_ifstream_get ();
static void CPP_14__method_ifstream_get__const_buf ();
static void CPP_15__method_ifstream_get__streambuf ();
static void CPP_16__iostream_iterators__copy ();
static void CPP_17__iostream_iterators__string ();
static void CPP_18__iostreambuf_iterators__copy ();
static void CPP_19__iostreambuf_iterators__transform ();
static void CPP_20__iostreambuf_iterators__string ();
static void CPP_21__vector__copy ();
static void CPP_22__vector_push_back ();
static void CPP_23__vector__cpp_read ();
static void CPP_24__string__cpp_read ();

static void measure (std::size_t no_of_repetitions);
static void show (std::size_t no_of_tests);
static void run (std::size_t no_of_runs, std::size_t no_of_tests, std::size_t no_of_repetitions);


// ========================================
// ====== Part-1: Common Auxilary Functions
// ========================================


// ---------------------------
// Function 1.01
std::string getCompilationMachineName () 
{
    std::ostringstream oss;
#ifdef _WIN32
    // ???

// ----------------------------------
#elif defined __hpux
#ifdef PSP_MAX_CACHE_LEVELS 
    oss << "HP-UX v3 or higher";
#else
    oss << "HP-UX v2 or lower";
#endif

// ----------------------------------
#elif (defined __sun || defined __sun__)

#if defined __SunOS_5_11
    oss << "SunOS 5.11";
#elif defined __SunOS_5_10
    oss << "SunOS 5.10";
#elif defined __SunOS_5_9
    oss << "SunOS 5.9";
#elif defined __SunOS_5_8
    oss << "SunOS 5.8";
#elif defined __SunOS_5_7
    oss << "SunOS 5.7";
#elif defined __SunOS_5_6
    oss << "SunOS 5.6";
#else
    oss << "SunOS - Unknown model";
#endif

// ----------------------------------
#elif (defined __aix || defined __aix__)

#if defined _AIX62
    oss << "AIX 6.2";
#elif defined _AIX61
    oss << "AIX 6.1";
#elif defined _AIX53
    oss << "AIX 5.3";
#elif defined _AIX52
    oss << "AIX 5.2";
#elif defined _AIX51
    oss << "AIX 5.1";
#elif defined _AIX50
    oss << "AIX 5.0";
#elif defined _AIX43
    oss << "AIX 4.3";
#elif defined _AIX41
    oss << "AIX 4.1";
#elif defined _AIX32
    oss << "AIX 3.2";
#else
    oss << "AIX - Unknown model";
#endif

#elif (defined __linux)
     oss << "Linux (Release not available in compile-time)";

// ----------------------------------
#else  // i.e. neither _WIN32, nor __unix
#error Method getCompilationMachineName() not implemented on this architecture/compiler
#endif  

    if (oss.str().empty())
    {
    oss << "???";
    }
    
    return oss.str();
}

// ------------------------------------
// Function 1.02
std::string getRunMachineName (bool i_detailedInfo) 
{
    std::string retMachineName;
#ifdef _WIN32
    const DWORD INFO_BUFFER_SIZE = 32767;
    TCHAR       infoBuf[INFO_BUFFER_SIZE];
    DWORD       bufCharCount = INFO_BUFFER_SIZE;

    if (::GetComputerName(infoBuf, &bufCharCount))
    {
#ifdef UNICODE
        BOOST_STATIC_ASSERT(sizeof (TCHAR) == sizeof (wchar_t));
        std::wostringstream toss;
        std::wstring        tstr;
#else
        BOOST_STATIC_ASSERT(sizeof (TCHAR) == sizeof (char));
        std::ostringstream toss;
        std::string        tstr;
#endif
        toss << (TCHAR*) infoBuf;           
        tstr = toss.str();
        retMachineName = std::string(tstr.begin(), tstr.end()); 
    }

#elif defined __unix
    struct utsname machineInfo;
    if (uname (&machineInfo) >= 0)
    {
        std::ostringstream oss;
        oss << machineInfo.nodename;
        if (i_detailedInfo)
        {
            oss << " "
                << machineInfo.sysname
                << " "
                << machineInfo.release
                << " "
                << machineInfo.version
                << " "
                << machineInfo.machine;
                //<< " "
                //<< machineInfo.idnumber;
        }
        retMachineName = oss.str();
    }

#else  // i.e. neither _WIN32, nor __unix
#error Method getRunMachineName() not implemented on this architecture/compiler
#endif  

    if (retMachineName.empty())
    {
    retMachineName = "???";
    }
    return retMachineName;
}



// ------------------------------
// Function 1.03
std::string get_compiler_info()
{

    // ------------------------------------------
    // Various stuff was used including:
    // ------------------------------------------

    std::ostringstream oss;
    std::ostringstream tss;
    std::string strMajor;
    std::string strMinor;
    std::string strExtension;

    std::string::size_type minorStartId = 0;
    std::string::size_type extentionStartId = 0;
   
    std::ostringstream ossGNUgcc;
   
#ifdef __GNUC__

// ===================
    // -------------------------------------------
    // ----------------- GNU gcc -----------------
    // -------------------------------------------

    assert(ossGNUgcc.str().empty());

    ossGNUgcc << "GNU gcc " << __GNUC__;

#ifdef __GNUC_MINOR__
    ossGNUgcc << "." << __GNUC_MINOR__;

#ifdef __GNUC_PATCHLEVEL__
#if __GNUC_PATCHLEVEL__
    ossGNUgcc << "." << __GNUC_PATCHLEVEL__;

#endif      // #ifdef __GNUC_PATCHLEVEL__

#endif      // #if __GNUC_PATCHLEVEL__

#endif      // #ifdef __GNUC_MINOR__

#endif // #ifdef __GNUC__
   

// ====================================
#if (defined _WIN32 && defined _MSC_VER)
// ====================================
    // -------------------------------------------
    // -------------- Microsoft C++ --------------
    // _MSC_VER - VVRR : VV = Version, RR = Revision
    // Example: 1200 = Visual C++ 6.0 (compiler 12.0)
    //          1300 = Visual C++ 7.0 (compiler 13.0)
    //          1400 = Visual C++ 8.0 (compiler 14.0)
    //          1500 = Visual C++ 9.0 (compiler 15.0)
    //
    // _MSC_FULL_VER - VVRRPPPPP : VV = Version, RR = Revision, PPPPP = Patch
    // From Visual C++ 8.0 (i.e. compiler 14.0) ?
    // Note. _MSC_FULL_VER is not officially documented by the vendor
    // -------------------------------------------

    assert(oss.str().empty());
    assert(tss.str().empty());
    assert(strMajor.empty());
    assert(strMinor.empty());
    assert(strExtension.empty());
  
    oss << "Microsoft C/C++ ";
    tss << _MSC_VER;

    const std::size_t widthMinorVersion = 2;
    minorStartId = tss.str().size() - widthMinorVersion;

    strMinor = tss.str().substr(minorStartId);
    strMajor = tss.str().substr(0, minorStartId);

    oss << strMajor << "." << strMinor;

#ifdef _MSC_FULL_VER
    tss.str("");
    tss << _MSC_FULL_VER;
    const std::size_t widthMajorVersion = 2;
    const std::size_t widthPath = tss.str().size() - widthMajorVersion - widthMinorVersion;
    const std::string::size_type pathStartId = tss.str().size() - widthPath;
    const std::string strPath = tss.str().substr(pathStartId);

    oss << "." << strPath;

#endif      // #ifdef _MSC_FULL_VER

#ifdef _MANAGED
#if _MANAGED
    oss << " (Managed)";
#else       // #if _MANAGED
    assert(0);
    oss << " (-- Unmanaged)";
#endif      // #if _MANAGED
#else       // #ifdef _MANAGED
    oss << " (Unmanaged)";
#endif      // #ifdef _MANAGED



// ===================   
#elif (defined __GNUC__ && !defined __INTEL_COMPILER)  // Intel compiler has defined __GNUC__

// ===================
    // -------------------------------------------
    // ----------------- GNU gcc -----------------
    // -------------------------------------------

    assert(oss.str().empty());
    assert(tss.str().empty());
    assert(strMajor.empty());
    assert(strMinor.empty());
    assert(strExtension.empty());

    oss << ossGNUgcc.str();

   
// =======================================
#elif (defined __hpux && defined __HP_aCC)
// =======================================
    // -------------------------------------------
    // ------------------ HP aCC -----------------
    // __HP_aCC identifies the HP aC++ compiler driver version. 
    // It is represented as a 6-digit number in the format mmnnxx, 
    // where mm is the major version number, nn is the minor version number, 
    // and xx is any extension. 
    // For example, for version A.01.21, __HP_aCC=012100.
    // --------------------------------
    // Attention: Can be also mnnxx
    // For example, for version A.06.15
    // #define __HP_aCC 61500
    // -------------------------------------------
    
    assert(oss.str().empty());
    assert(tss.str().empty());
    assert(strMajor.empty());
    assert(strMinor.empty());
    assert(strExtension.empty());

    oss << "HP C/aC++ A.";

    tss << __HP_aCC;

    const std::size_t widthExtentionVersion = 2;    // xx from mmnnxx
    const std::size_t widthMinorVersion = 2;        // nn from mmnnxx
    const std::size_t maxWidthMajorVersion = 2;     // mm from mmnnxx

    extentionStartId = tss.str().size() - widthExtentionVersion;
    minorStartId     = extentionStartId - widthMinorVersion;

    strExtension = tss.str().substr(extentionStartId);
    strMinor = tss.str().substr(minorStartId, widthMinorVersion);
    strMajor = tss.str().substr(0, minorStartId);

    oss << ""
        << std::setw(maxWidthMajorVersion)
        << std::setfill ('0')
        << strMajor 
        << "." 
        << strMinor;
    if (strExtension != "00")
    {
        oss << ""
            << "." 
            << strExtension;
    }
    
 
// ==========================================================
#elif ((defined __aix || defined __aix__) && defined __xlC__)
// ========================================================== 
    // -------------------------------------------
    // ------------------ AIX xlC ----------------
    // __xlC__ indicates the level of the XL C++ compiler. 
    // Using the XL C compiler also automatically defines this macro.
    // A four-digit hexadecimal integer in the format 0xVVRM, where: 
    // V Represents the version number, 
    // R Represents the release number, 
    // M Represents the modification number.
    // For example, in XL C/C++ V9.0, the value of the macro is 0x0900.
    // -------------------------------------------

    assert(oss.str().empty());
    assert(tss.str().empty());
    assert(strMajor.empty());
    assert(strMinor.empty());
    assert(strExtension.empty());

    oss << "IBM XL C/C++ V";

    enum FieldsWidhts
    {
        fwMODIFICATION_WIDTH = 1,   // M from 0xVVRM
        fwRELEASE_WIDTH      = 1,   // R from 0xVVRM
        fwVERSION_WIDTH      = 2    // VV from 0xVVRM
    };

    const std::size_t fullVersion = static_cast<std::size_t>(__xlC__);
    const std::size_t compilerModification = adj::getLSBnibbles<fwMODIFICATION_WIDTH>(fullVersion);
    const std::size_t compilerRelease = adj::getNibbles (fullVersion, fwMODIFICATION_WIDTH, fwRELEASE_WIDTH);
    const std::size_t compilerVersion = adj::getNibbles (fullVersion, fwMODIFICATION_WIDTH + fwRELEASE_WIDTH, fwVERSION_WIDTH);

   
    oss << ""
        << std::setw(fwVERSION_WIDTH)
        << std::setfill ('0')
        << std::hex
        << compilerVersion 
        << "." 
        << compilerRelease;
    if (compilerModification != 0)
    {
        oss << ""
            << "." 
            << compilerModification;
    }

    oss << std::dec;

    oss << " for AIX";
    

// ==============================================================
#elif ((defined __sun || defined __sun__) && defined __SUNPRO_CC)
// ==============================================================
    // ------------------ SUN CC ----------------
    // __SUNPRO_CC indicates the level of the SUN CC compiler.
    // -------------------------------------------------------------
    // For Version <= 5.9: 
    // A three-digit hexadecimal integer in the format 0xVRP, where: 
    // V Represents the Version number, 
    // R Represents the Revision number, 
    // P Represents the Patch number.
    // For example, in Sun C++ 5.9, the value of the macro is 0x590.
    // -------------------------------------------------------------
    // For Version >= 5.10
    // A four-digit hexadecimal integer in the format 0xVRRP, where: 
    // V  Represents the Version number, 
    // RR Represents the Revision number, 
    // P  Represents the Patch number.
    // For example, in Sun C++ 5.10, the value of the macro is 0x5100.
    // -------------------------------------------

    assert(oss.str().empty());
    assert(tss.str().empty());
    assert(strMajor.empty());
    assert(strMinor.empty());
    assert(strExtension.empty());

    oss << "Sun C++ ";

    enum FieldsWidhts
    {
        fwPATCH_WIDTH = 1,          // P from 0xVRP or 0xVRRP
        fwREVISION_WIDTH = (__SUNPRO_CC <= 0xfff) ? 1 : 2,  // R from 0xVRP or RR from 0xVRRP
        fwVERSION_WIDTH = 1         // V from 0xVRP or 0xVRRP
    };

    const std::size_t fullVersion = static_cast<std::size_t>(__SUNPRO_CC);
    const std::size_t compilerPatch = adj::getLSBnibbles<fwPATCH_WIDTH>(fullVersion);
    const std::size_t compilerRevision = adj::getNibbles (fullVersion, fwPATCH_WIDTH, fwREVISION_WIDTH);
    const std::size_t compilerVersion = adj::getNibbles (fullVersion, fwPATCH_WIDTH + fwREVISION_WIDTH, fwVERSION_WIDTH);

   
    oss << ""
        << std::setw(fwVERSION_WIDTH)
        << std::setfill ('0')
        << std::hex
        << compilerVersion 
        << "." 
        << compilerRevision;
    if (compilerPatch != 0)
    {
        oss << ""
            << "." 
            << compilerPatch;
    }
    oss << std::dec;



// =============================
#elif (defined __INTEL_COMPILER)
// =============================
    // -------------------------------------------
    // ------------------ Intel icpc ----------------
    // __INTEL_COMPILER indicates the level of the Intel C++ compiler. 
    // __INTEL_COMPILER = VVRP
    //   VV = version, 
    //   R = Revision, 
    //   P = Patch
    // 
    // __INTEL_COMPILER_BUILD_DATE indicates build date
    // __INTEL_COMPILER_BUILD_DATE = YYYYMMDD
    //   YYYY = Year
    //   MM = Month
    //   DD = Day
    // -------------------------------------------

    assert(oss.str().empty());
    assert(tss.str().empty());
    assert(strMajor.empty());
    assert(strMinor.empty());
    assert(strExtension.empty());

    oss << "Intel(R) C++ Intel(R) 64 Compiler, Version ";

    tss << __INTEL_COMPILER;

    const std::size_t widthPatchVersion = 1;        // P from R from VVRP
    const std::size_t widthReleaserVersion = 1;     // R from VVRP
    const std::size_t maxWidthVersion = 2;          // VV from VVRP

    extentionStartId = tss.str().size() - widthPatchVersion;
    minorStartId     = extentionStartId - widthReleaserVersion;

    strExtension = tss.str().substr(extentionStartId);
    strMinor = tss.str().substr(minorStartId, widthReleaserVersion);
    strMajor = tss.str().substr(0, minorStartId);

    oss << ""
        << std::setw(maxWidthVersion)
        << std::setfill ('0')
        << strMajor 
        << "." 
        << strMinor;
    if (strExtension != "00")
    {
        oss << ""
            << "." 
            << strExtension;
    }

    oss << "; Build "
        << __INTEL_COMPILER_BUILD_DATE;
        
    // --------------------
#ifdef __VERSION__
oss << "; "
   << __VERSION__;
#endif // __VERSION__

#ifdef __GNUC__
oss << "; "
   << "Compatibility - ";
   
if (ossGNUgcc.str().empty())
{
oss << "None";
}
else
{
oss << ossGNUgcc.str();
}
   
#endif // __GNUC__
    

#else
#error Method Utils::getCompilerInfo () not implemented for this compiler    
#endif  // #if (defined _WIN32 && defined _MSC_VER)
    

    // -----------------
    if (oss.str().empty())
    {
    oss << "???";
    }
    
    return oss.str();
} // get_compiler_info



// -----------------------------
// Function 1.04
void show_env_info()
// -----------------------------
{
std::ostringstream ossCompilationMachine;
ossCompilationMachine << ""
                      << "Compilation Machine:  "
                      << getCompilationMachineName();
std::ostringstream ossRunMachine;
ossRunMachine << ""
<< "Run Machine:  "
 << getRunMachineName(true);
 
std::ostringstream ossCompiler;
ossCompiler << ""
<< "Compiler:  "
 << get_compiler_info();
 
const std::string& strCompilationMachine = ossCompilationMachine.str();
const std::string& strRunMachine = ossRunMachine.str();
const std::string& strCompiler = ossCompiler.str();

  std::cout << std::string (strCompilationMachine.size(), '-') << std::endl;
  std::cout << strCompilationMachine << std::endl;
  std::cout << std::string (strCompilationMachine.size(), '-') << std::endl;
 
  std::cout << std::endl;
 
  std::cout << std::string (strRunMachine.size(), '-') << std::endl;
  std::cout << strRunMachine << std::endl;
  std::cout << std::string (strRunMachine.size(), '-') << std::endl;
 
  std::cout << std::endl;
 
  std::cout << std::string (strCompiler.size(), '-') << std::endl;
  std::cout << strCompiler << std::endl;
  std::cout << std::string (strCompiler.size(), '-') << std::endl;
}



// ----------------------------------------
// Function 1.05
std::size_t getFileSize (const std::string& i_fileName, const bool i_mode) 
return getFileSizeViaSeekgTellg(i_fileName, i_mode);
}

// ----------------------------------------
// Function 1.06
std::size_t getFileSizeViaSeekgTellg (const std::string& i_fileName, const bool i_mode) 
    if (i_fileName.empty())
    {
        return std::numeric_limits<std::size_t>::max();
    }
    assert(!i_fileName.empty());

    std::ifstream fs; 

    if (i_mode) 
{
     fs.open (i_fileName.c_str()); 
    }
    else
{
fs.open (i_fileName.c_str(), std::ios::binary); 
}
if (!fs)
{
return std::numeric_limits<std::size_t>::max();
}
  assert(fs); 
  
  if (!fs.is_open())
{
return std::numeric_limits<std::size_t>::max();
}
    assert(fs.is_open()); 

fs.seekg(0, std::ios::beg); 
const std::ios::pos_type startPos = fs.tellg();
  if (!fs.good())
  {
    return std::numeric_limits<std::size_t>::max();
  }
assert(fs.good()); 
// assert(static_cast<std::size_t>(startPos) == 0);

  fs.seekg(0, std::ios::end); 
const std::ios::pos_type endPos = fs.tellg();
if (endPos == static_cast<std::ios::pos_type>(-1))
  {
    return std::numeric_limits<std::size_t>::max();
  }
  assert(static_cast<std::ios::pos_type>(-1) != endPos);

const std::size_t retFileSize (static_cast<std::size_t>(endPos - startPos)); 

    fs.close(); 
    assert(!fs.is_open()); 

    return retFileSize; 





// --------------------------------
// Function 1.07
std::string file2string (
std::ifstream& io_fin,
std::size_t    i_filesize
)
// --------------------------------
{
  ASSERT (!io_fin.bad());

  ASSERT (io_fin);
  ASSERT (io_fin.is_open());

const std::ios::iostate prev_state = io_fin.rdstate(); 
const std::ios::pos_type prev_pos  = io_fin.tellg();  


std::string str (i_filesize, '0');

  // ---------------------
  io_fin.clear();
  io_fin.seekg(0, std::ios::beg);

char ch;
std::size_t i;
  for (i = 0; io_fin.get (ch); i++)
  {
    ASSERT (i < str.size());
    str[i] = ch;
  }

  ASSERT (i <= i_filesize);
  str.erase (i);

  // ---------------------------
  io_fin.clear(prev_state);
  io_fin.seekg(prev_pos, std::ios::beg);

  ASSERT (prev_state == io_fin.rdstate());
  ASSERT (prev_pos   == io_fin.tellg());
  // ---------------------------

  return str;

} // file2string (1)

// ====================================================
// Function 1.08
std::string file2string (
const char * const i_fileName, 
const bool         i_mode
)
// ====================================================
{
std::ifstream fin;

  if (i_mode)
  { 
    fin.open (i_fileName);
  }
  else
  {               
    fin.open (i_fileName, std::ios::binary);
  }

  ASSERT (fin);
  ASSERT (fin.is_open());

const std::size_t filesize (getFileSize (i_fileName, i_mode));
const std::string str (file2string (fin, filesize));

  fin.close();
  ASSERT (!fin.is_open());

  return str;

} // file2string (2)



// ===================================
// ====== Part-2: Static Data & Defines
// ===================================

// --------------------------------------
static std::vector<std::string>           s_funcNames;
static std::vector<std::string>::iterator s_iterNames;
static std::vector<std::vector<clock_t> > s_usedTime;

static std::size_t  s_numberOfRuns = 0;
static std::size_t  s_numberOfTests = 0;


static std::size_t s_userDefinedFileSize = 0;
static std::size_t s_infileSize          = 0;

static std::string s_strInfileConstent;

static std::size_t   s_funcSetw = 0;

// ------------------------------
#define SMART_ASSERT(x) if (!(x)) { std::cerr << "SOURCE LINENo = " << i_lineNo << std::endl; ASSERT(x); abort(); }

#define OPEN_FP_OUT openFpOut (__LINE__)
#define OPEN_FD_OUT openFdOut (__LINE__)
#define OPEN_FS_OUT openFsOut (__LINE__)

#define CLOSE_FP_OUT closeFpOut (__LINE__)
#define CLOSE_FD_OUT closeFdOut (__LINE__)
#define CLOSE_FS_OUT close_s_fsOut (__LINE__)


#define TRACE(x) 
// #define TRACE(x)  std::cerr << x << std::endl


// ------------------------------
#define INPUT_FILE_NAME   "testCopyFiles.in"
#define OUTPUT_FILE_NAME  "testCopyFiles.out"

static FILE* s_fpIn;
static FILE* s_fpOut;

#ifdef __unix
static int s_fdIn;
static int s_fdOut;
#endif

static std::ifstream s_fsIn;
static std::ofstream s_fsOut;

#define BUFFER_SIZE  4096

static char* s_pMbuffer = 0;




// =======================================
// ====== Part-3: Local Auxilary Functions
// =======================================

// -----------------------------
// Function 3.01
void auxCheckAssertOut (
const char * const i_fileName,  
const std::size_t  i_lineNo
)
// -----------------------------
{
const std::string outfile_content (file2string(i_fileName));

const std::string strInfileContent (s_strInfileConstent);

  if (!(strInfileContent.size() == s_userDefinedFileSize))
  {
    std::cerr << "FATAL ERROR: infile size = " 
         << strInfileContent.size() 
         << ", " 
         << i_fileName 
         << " s_userDefinedFileSize = "
         << s_userDefinedFileSize
         << std::endl;
  }


  SMART_ASSERT ((strInfileContent.size() == s_userDefinedFileSize));

  if (!(strInfileContent.size() == outfile_content.size()))
  {
    std::cerr << "FATAL ERROR: infile size = " 
         << strInfileContent.size() 
         << ", " 
         << i_fileName 
         << " outfile size = "
         << outfile_content.size()
         << std::endl;
  }

  SMART_ASSERT ((strInfileContent.size() == outfile_content.size()));
  SMART_ASSERT ((strInfileContent == outfile_content));
}

// -------------- Level-1 -----------------
// ----------------------------------------

// -----------------------------
// Function 3.02
void auxOpenFpOut (
const char * const i_fileName, 
FILE*&       o_fp, 
const char * const i_mode,
const std::size_t  i_lineNo
)
// -----------------------------
{
  TRACE("\n" << __FUNCTION__ << " : Start  -> " << i_fileName);

const int rc = remove (i_fileName);  
  SMART_ASSERT (!(rc == 0));

  o_fp = fopen(i_fileName, i_mode);
  SMART_ASSERT(o_fp);

  TRACE(__FUNCTION__ << " : Finish -> " << i_fileName);
}

// --------------------------------
// Function 3.03
void auxCloseFpOut (
const char * const i_fileName, 
FILE*&             o_fp,
const std::size_t  i_lineNo
)
// --------------------------------
{
  TRACE(__FUNCTION__ << " : Start  -> " << i_fileName);

  auxCheckAssertOut (i_fileName, i_lineNo);

int rc;

  clearerr(o_fp);
  rc = fclose(o_fp);
  SMART_ASSERT (rc == 0);

  rc = remove (i_fileName);  
  SMART_ASSERT (rc == 0);

  TRACE(__FUNCTION__ << " : Finish -> " << i_fileName);

}


#ifdef __unix
// --------------------------------
// Function 3.04
void auxOpenFdOut (
const char * const i_fileName, 
int&               o_fdOut, 
const int          i_fdIn, 
const std::size_t  i_lineNo
)
// --------------------------------
{
  TRACE("\n" << __FUNCTION__ << " : Start  -> " << i_fileName << ", fd = " << o_fdOut << ", mode = " << i_mode);

const int rc = remove (i_fileName);  
  SMART_ASSERT (!(rc == 0));

  o_fdOut = open(i_fileName, O_CREAT | O_RDWR);
  chmod (i_fileName, 0666);

  SMART_ASSERT (o_fdOut != -1);
  SMART_ASSERT (i_fdIn != o_fdOut);

  TRACE(__FUNCTION__ << " : Finish -> " << i_fileName << ", fd = " << o_fdOut);
}


// --------------------------------
// Function 3.05
void auxCloseFdOut (
const char * const i_fileName, 
int&               fd_o, 
const std::size_t  i_lineNo
)
// --------------------------------
{
  TRACE(__FUNCTION__ << " : Start  -> " << i_fileName << ", fd = " << fd_o << ", mode = " << i_mode);

  auxCheckAssertOut (i_fileName, i_lineNo);

int rc;

  rc = close(fd_o);
  SMART_ASSERT(rc == 0);

  rc = remove (i_fileName);  
  SMART_ASSERT (rc == 0);

  TRACE(__FUNCTION__ << " : Finish -> " << i_fileName << ", fd = " << fd_o);
}
#endif


// --------------------------------
// Function 3.06
void auxOpenFsOut (
const char * const i_fileName, 
std::ofstream&    fs_o, 
const std::size_t i_lineNo,
const bool i_mode
)
// --------------------------------
{
  TRACE("\n" << __FUNCTION__ << " : Start  -> " << i_fileName);

const int rc = remove (i_fileName);  
  SMART_ASSERT (!(rc == 0));

  fs_o.clear();
  if (i_mode)
  { 
    fs_o.open (i_fileName);
  }
  else
  {
    fs_o.open (i_fileName, std::ios::binary);
  }

  SMART_ASSERT (fs_o);
  SMART_ASSERT (fs_o.is_open());

  TRACE(__FUNCTION__ << " : Finish -> " << i_fileName);
}

 

// --------------------------------
// Function 3.07
void auxCloseFsOut (
const char * const i_fileName, 
std::ofstream&     fs_o,
const std::size_t  i_lineNo
)
// --------------------------------
{
  TRACE(__FUNCTION__ << " : Start  -> " << i_fileName);

  fs_o.clear();
  fs_o.seekp (0, std::ios::beg);

  auxCheckAssertOut (i_fileName, i_lineNo);

  fs_o.clear();
  fs_o.close();
  SMART_ASSERT (!fs_o.is_open());

const int rc = remove (i_fileName);  
  SMART_ASSERT (rc == 0);

  TRACE(__FUNCTION__ << " : Finish -> " << i_fileName);
}


// -------------- Level-2 -----------------
// ----------------------------------------

// --------------------------------------
// Function 3.08
void openFpOut (const std::size_t i_lineNo)
// --------------------------------------
{
  auxOpenFpOut (OUTPUT_FILE_NAME, s_fpOut, "w", i_lineNo);
}


// ---------------------------------------
// Function 3.09
void closeFpOut (const std::size_t i_lineNo)
// ---------------------------------------
{
  auxCloseFpOut (OUTPUT_FILE_NAME, s_fpOut, i_lineNo);
}


#ifdef __unix
// --------------------------------------
// Function 3.10
void openFdOut (const std::size_t i_lineNo)
// --------------------------------------
{
  auxOpenFdOut (OUTPUT_FILE_NAME, s_fdOut, s_fdIn, i_lineNo);
}

// ---------------------------------------
// Function 3.11
void closeFdOut (const std::size_t i_lineNo)
// ---------------------------------------
{
  auxCloseFdOut (OUTPUT_FILE_NAME, s_fdOut, i_lineNo);
}


#endif


// --------------------------------------
// Function 3.12
void openFsOut (const std::size_t i_lineNo)
// --------------------------------------
{
  auxOpenFsOut (OUTPUT_FILE_NAME, s_fsOut, true, i_lineNo);
}



// ---------------------------------------
// Function 3.13
void close_s_fsOut (const std::size_t i_lineNo)
// ---------------------------------------
{
  auxCloseFsOut (OUTPUT_FILE_NAME, s_fsOut, i_lineNo);
}



// ==========================================
// ====== Part-4: Locat Preparation Functions
// ==========================================


// ---------------------------------------
// Function 4.01
void fillInputFile (std::size_t total_full_rows)
// ---------------------------------------
{
  ASSERT (total_full_rows > 0);
  if (s_userDefinedFileSize < total_full_rows)
  {
    total_full_rows = s_userDefinedFileSize;
  }
  ASSERT (total_full_rows <= s_userDefinedFileSize);

  remove (INPUT_FILE_NAME);

std::ofstream test_infile (INPUT_FILE_NAME);
  ASSERT (test_infile);
  ASSERT (test_infile.is_open());

const std::size_t row_size (s_userDefinedFileSize/total_full_rows);


#define START_CH 0
char ch = START_CH;

std::size_t counter = 0;
  for (std::size_t row_no = 0; row_no < total_full_rows; row_no++)
  {
    for (std::size_t ch_no = 0; ch_no < row_size; ch_no++)
    {
      while (!isprint(ch))
      { 
        ch++;
      }
      ASSERT (counter < s_userDefinedFileSize);

      test_infile << ch;
      ch++;
      counter++;
      if (counter == s_userDefinedFileSize)
      { 
        break;
      }

      if (ch == SCHAR_MAX)
      { 
        ch = START_CH;
      }
    }

    if (counter == s_userDefinedFileSize)
    { 
      break;
    }
    ASSERT (counter < s_userDefinedFileSize);

    test_infile << '\n';
    counter++;
    if (counter == s_userDefinedFileSize)
    { 
      break;
    }
  }

  test_infile.close();
  ASSERT (!test_infile.is_open());

  s_strInfileConstent = file2string (INPUT_FILE_NAME, true);

  s_infileSize = s_strInfileConstent.size();                  

  if (!(s_infileSize != s_userDefinedFileSize))
  {
    std::cerr << "User defined filesize = " << s_userDefinedFileSize << std::endl;
    std::cerr << "Input file size       = " << s_infileSize << std::endl;
  }

  ASSERT (s_infileSize == s_userDefinedFileSize);



} // fillInputFile


// ====================================
// ====== Part-5: Function To Be Tested
// ====================================

// --------------------------------------
void C_01__functions_getc_putc ()
{
int      int_ch;

  clearerr(s_fpIn);
  rewind (s_fpIn);

  // ------ Body ------
  while ((int_ch = getc(s_fpIn)) != EOF) 
  {
    putc(int_ch, s_fpOut);
  }
  // ------------------

  clearerr(s_fpOut);
  rewind (s_fpOut);
}

// --------------------------------------
void C_02__functions_fgetc_fputc ()
{
int      int_ch;

  clearerr(s_fpIn);
  rewind (s_fpIn);

  // ------ Body ------
  while ((int_ch = fgetc(s_fpIn)) != EOF)
  {
    fputc(int_ch, s_fpOut);
  }
  // ------------------

  clearerr(s_fpOut);
  rewind (s_fpOut);
}


// --------------------------------------
void C_03__functions_fread_fwrite__const_buf ()
{
char     cbuffer[BUFFER_SIZE];
std::size_t   nread;

  clearerr(s_fpIn);
  rewind (s_fpIn);

  // ------ Body ------
  while ((nread = fread(cbuffer, sizeof(char), sizeof(cbuffer), s_fpIn)) > 0)
  {
    fwrite(cbuffer, sizeof(char), nread, s_fpOut);
  }
  // ------------------

  clearerr(s_fpOut);
  rewind (s_fpOut);
}


// --------------------------------------
void C_04__functions_fread_fwrite__max_buf ()
{
std::size_t   nread;

  clearerr(s_fpIn);
  rewind (s_fpIn);

  // ------ Body ------
  while ((nread = fread(s_pMbuffer, sizeof(char), s_infileSize, s_fpIn)) > 0)
  {
    fwrite(s_pMbuffer, sizeof(char), nread, s_fpOut);
  }
  // ------------------

  clearerr(s_fpOut);
  rewind (s_fpOut);
}


#ifdef __unix
// --------------------------------------
void C_UNIX_01__mmap_write ()
{
off_t rc;
  rc = lseek(s_fdIn, 0, SEEK_SET);
  ASSERT (rc != -1);
  rc = lseek(s_fdOut, 0, SEEK_SET);
  ASSERT (rc != -1);

  // ------ Body ------
char* ptr = (char*)mmap(0, s_infileSize, PROT_READ, MAP_SHARED, s_fdIn, 0);
  ASSERT (ptr != MAP_FAILED);
  write(s_fdOut, ptr, s_infileSize);
  rc = munmap(ptr, s_infileSize);
  ASSERT (rc == 0);
  
  // ------------------
}


// --------------------------------------
void C_UNIX_02__mmap_memcpy ()
{
off_t rc;
  rc = lseek(s_fdIn, 0, SEEK_SET);
  ASSERT (rc != -1);
  rc = lseek(s_fdOut, 0, SEEK_SET);
  ASSERT (rc != -1);

  // ------ Body ------
char* pIn = (char*)mmap(0, s_infileSize, PROT_READ, MAP_SHARED, s_fdIn, 0);
  ASSERT (pIn != MAP_FAILED);
  

const int result = ftruncate(s_fdOut, s_infileSize);
   ASSERT (result == 0);
char* pOut = (char*)mmap(0, s_infileSize, PROT_READ | PROT_WRITE, MAP_SHARED, s_fdOut, 0);
  ASSERT (pOut != MAP_FAILED);
  
  memcpy(pOut, pIn, s_infileSize);
  
  rc = munmap(pIn, s_infileSize);
  ASSERT (rc == 0);
  
  rc = munmap(pOut, s_infileSize);
  ASSERT (rc == 0);
  // ------------------
}


#endif

// --------------------------------------
void CPP_01__operators_in_out ()
{
char ch;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsIn.unsetf(std::ios::skipws);
  while (s_fsIn >> ch)
  { 
    s_fsOut << ch;
  }
  // ------------------

}


// --------------------------------------
void CPP_02__methods_sbumpc_sputc ()
{
char ch;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  while ((ch = static_cast<char>(s_fsIn.rdbuf()->sbumpc())) != EOF)
  {
    s_fsOut.rdbuf()->sputc(ch);
  }
  // ------------------

}


// --------------------------------------
void CPP_03__method_sbumpc__op_out ()
{
char ch;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  ch = static_cast<char>(s_fsIn.rdbuf()->sbumpc());
  s_fsOut << ch;

  while (ch != EOF)
  {
    s_fsOut << s_fsIn.rdbuf();
    ch = static_cast<char>(s_fsIn.rdbuf()->sbumpc());
  }

}

// --------------------------------------
void CPP_04__method_rdbuf__op_out ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsOut << s_fsIn.rdbuf();
  // ------------------

}



// --------------------------------------
void CPP_05__methods_cpp_read_write__const_buf ()
{
char cbuffer[BUFFER_SIZE];

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  while (!s_fsIn.eof())
  {
    s_fsIn.read (cbuffer, sizeof(cbuffer));
    s_fsOut.write (cbuffer, s_fsIn.gcount());
  }
  // ------------------

}



// --------------------------------------
void CPP_06__methods_cpp_read_write_oss__const_buf ()
{
char cbuffer[BUFFER_SIZE];
std::ostringstream oss;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  while (!s_fsIn.eof())
  {
    s_fsIn.read (cbuffer, sizeof(cbuffer));
    oss.write (cbuffer, s_fsIn.gcount());
  }
  s_fsOut << oss.str();
  // ------------------

}



// --------------------------------------
void CPP_07__methods_cpp_readsome_write__const_buf ()
{
char cbuffer[BUFFER_SIZE];
std::streamsize len;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  do
  { 
    len = s_fsIn.readsome (cbuffer, sizeof(cbuffer)); 
    s_fsOut.write (cbuffer, len);
  } while (len); 
  // ------------------
}


// --------------------------------------
void CPP_08__methods_cpp_read_write__max_buf ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  while (!s_fsIn.eof())
  {
    s_fsIn.read (s_pMbuffer, s_infileSize);
    s_fsOut.write (s_pMbuffer, s_fsIn.gcount());
  }

  // ------------------

}

// --------------------------------------
void CPP_09__function_getline__ostringstream ()
{
std::string line;
std::ostringstream oss;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  while (std::getline (s_fsIn, line)) 
  {
    oss << line << '\n';
  }
std::string str(oss.str());
  if (!str.empty())
  {
    s_fsIn.rdbuf()->sungetc ();
    if (s_fsIn.rdbuf()->sgetc() != '\n')
    { 
       str.erase(str.size() - 1);
    }
  }
  s_fsOut << str;
  // ------------------

}



// --------------------------------------
void CPP_10__function_getline__string ()
{
std::string str;
std::string line;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  while (std::getline (s_fsIn, line)) 
  {
    str +=line;
    str +='\n';
  }

  if (!str.empty())
  {
    s_fsIn.rdbuf()->sungetc ();
    if (s_fsIn.rdbuf()->sgetc() != '\n')
    { 
      str.erase(str.size() - 1);
    }
  }
  // ------------------
  s_fsOut << str;

}


// --------------------------------------
void CPP_11__method_ifstream_getline ()
{
char buffer[BUFFER_SIZE];
std::ostringstream oss;
  ASSERT (sizeof(buffer) > 1);

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  while (s_fsIn.getline (buffer, sizeof(buffer)).gcount())
  {
    oss << buffer;

    if (s_fsIn.fail()) 
    {
      s_fsIn.clear (~(std::ios_base::failbit | ~s_fsIn.rdstate ())); 
    }
    else
    {               
      oss << '\n';
    }
  }
  ASSERT (s_fsIn.eof());

std::string str(oss.str());
  if (!str.empty())
  {
    s_fsIn.rdbuf()->sungetc ();
    if (s_fsIn.rdbuf()->sgetc() != '\n') str.erase(str.size() - 1);
  }
  s_fsOut << str;
  // ------------------
}


// --------------------------------------
void CPP_12__methods_ifstream_get_put ()
{
char ch;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  while (s_fsIn.get(ch)) 
  {
    s_fsOut.put(ch);
  }
  // ------------------

}


// --------------------------------------
void CPP_13__method_ifstream_get ()
{
std::string str (s_infileSize + 1, '0');
char ch;
std::size_t i;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  for (i = 0; s_fsIn.get (ch); i++)
  {
    str[i] = ch;
  }
  str.erase (i);
  // ------------------
  s_fsOut << str;
}

// --------------------------------------
void CPP_14__method_ifstream_get__const_buf ()
{
char cbuffer[BUFFER_SIZE];

  ASSERT (sizeof(cbuffer) > 1);

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
const int newline_int_symbol (int ('\n'));
  while (s_fsIn.get (cbuffer, sizeof(cbuffer)))
  {
    s_fsOut << cbuffer;
    if (s_fsIn.peek() == newline_int_symbol)
    {
      s_fsOut << char(s_fsIn.get());
    }
  }
  // ------------------
}



// --------------------------------------
void CPP_15__method_ifstream_get__streambuf ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
const int newline_int_symbol (int ('\n'));
  while (s_fsIn.get (*s_fsOut.rdbuf()))
  {
    if (s_fsIn.peek() == newline_int_symbol)
    {
      s_fsOut << char(s_fsIn.get());
    }
  }
  // ------------------
}

// --------------------------------------
void CPP_16__iostream_iterators__copy ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsIn >> std::noskipws;
std::istream_iterator<char> in(s_fsIn), eos;
std::ostream_iterator<char> out(s_fsOut);
  std::copy (in, eos, out);
  // ------------------
}



// --------------------------------------
void CPP_17__iostream_iterators__string ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsIn >> std::noskipws;
  std::istream_iterator<char> in(s_fsIn), eos;
  // ------------------

  s_fsOut << std::string(in, eos);
}



// --------------------------------------
void CPP_18__iostreambuf_iterators__copy ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsIn >> std::noskipws;
std::istreambuf_iterator<char> in(s_fsIn), eos;
std::ostreambuf_iterator<char> out(s_fsOut);
  std::copy (in, eos, out);
  // ------------------

}

// --------------------------------------
struct char_identity
{
  char operator()(char ch) const { return ch; }
};

// --------------------------------------
void CPP_19__iostreambuf_iterators__transform ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsIn >> std::noskipws;
std::istreambuf_iterator<char> in(s_fsIn), eos;
std::ostreambuf_iterator<char> out(s_fsOut);
  transform(in, eos, out, char_identity());
  // ------------------

}



// --------------------------------------
void CPP_20__iostreambuf_iterators__string ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsIn >> std::noskipws;
  std::istreambuf_iterator<char> in(s_fsIn), eos;
  // ------------------

  s_fsOut << std::string(in, eos);
}



// --------------------------------------
void CPP_21__vector__copy ()
{
  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();;
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
std::vector<char> v (s_infileSize);
  s_fsIn.read(&v[0], s_infileSize);

std::ostream_iterator<char> out(s_fsOut);
  std::copy (&v[0], &v[v.size()], out);
  // ------------------

}



// --------------------------------------
void CPP_22__vector_push_back ()
{
std::vector<char> v;
char ch;

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();;
  s_fsOut.seekp (0, std::ios::beg);

  v.reserve(s_infileSize);
  // ------ Body ------
  while (s_fsIn.get(ch))
  { 
    v.push_back(ch);
  }
  // ------------------
  s_fsOut << (v.empty() ? std::string() : std::string (v.begin(), v.end()));

}


// --------------------------------------
void CPP_23__vector__cpp_read ()
{
std::vector<char> v (s_infileSize);

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();;
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsIn.read(&v[0], s_infileSize);
  // ------------------

  s_fsOut << (v.empty() ? std::string() : std::string (v.begin(), v.end()));

}



// --------------------------------------
void CPP_24__string__cpp_read ()
{
std::string str (s_infileSize, '0');

  s_fsIn.clear();
  s_fsIn.seekg (0, std::ios::beg);

  s_fsOut.clear();;
  s_fsOut.seekp (0, std::ios::beg);

  // ------ Body ------
  s_fsIn.read(&str[0], s_infileSize);
  // ------------------

  s_fsOut << str;

}


// =====================================
// ====== Part-6: Computation Management
// =====================================

// -----------------------------------
// -----------------------------------
// -----------------------------------
#define MEASURE_IT(x, y) \
  s_funcSetw = MAX_VALUE (s_funcSetw, std::string (#y).size()); \
  std::cerr << "[Run-" << s_numberOfRuns << "] Test-" << s_numberOfTests << ": " << #y << std::endl; \
  start_time = clock(); \
  ASSERT (start_time != clock_t (-1)); \
  { for (std::size_t k = 0; k < no_of_repetitions; k++) { x; } } \
  end_time = clock(); \
  ASSERT (end_time != clock_t (-1)); \
  if (!(end_time > start_time)) { std::cerr << "Number of repetitions too small: " << #y << std::endl; }\
  ASSERT (end_time >= start_time); \
  if (find (s_funcNames.begin(), s_funcNames.end(), #y) == s_funcNames.end()) \
  { \
    s_funcNames.push_back (#y); \
    s_usedTime.push_back (std::vector<clock_t>()); \
  } \
  ASSERT (s_funcNames.size() == s_usedTime.size()); \
  s_iterNames = find (s_funcNames.begin(), s_funcNames.end(), #y); \
  ASSERT (s_iterNames != s_funcNames.end()); \
  s_usedTime[std::distance (s_funcNames.begin(), s_iterNames)].push_back ((end_time - start_time))

#define MEASURE_WITH_ARG(foo, argument) MEASURE_IT (foo(argument), foo)
#define MEASURE_WITH_NO_ARG(foo) MEASURE_IT (foo(), foo)

// ------------
void measure (std::size_t no_of_repetitions)
{
clock_t start_time;
clock_t end_time;
std::vector<clock_t> elapsed_time_vect;

  // -------------------------------
  fillInputFile ();

  ASSERT (s_infileSize);

  s_pMbuffer = new (std::nothrow) char [s_infileSize + 1];

  ASSERT (s_pMbuffer != NULL);


  // -------------------------------
  s_fpIn  = fopen(INPUT_FILE_NAME, "r");
  ASSERT(s_fpIn);

  if (!(s_infileSize == getFileSize (INPUT_FILE_NAME, true)))
  {
    std::cerr << std::endl;
    std::cerr << "User defined file size = " << s_userDefinedFileSize << std::endl;
    std::cerr << "Input file size        = " << s_infileSize << std::endl;
    ASSERT (s_infileSize == getFileSize (INPUT_FILE_NAME, true));
  }
  ASSERT (s_infileSize == getFileSize (INPUT_FILE_NAME, true));

#ifdef __unix
  s_fdIn = open(INPUT_FILE_NAME, O_CREAT | O_RDONLY);
  ASSERT (s_fdIn != -1);

  ASSERT (s_infileSize == getFileSize (INPUT_FILE_NAME, true));

#endif

  s_fsIn.open (INPUT_FILE_NAME);
  ASSERT (s_fsIn);
  ASSERT (s_fsIn.is_open());
  
  ASSERT (s_infileSize == getFileSize (INPUT_FILE_NAME, true));


  // -------------------------------
  // std::cout << "\t---> Test-" << s_numberOfTests << " started" << std::endl;
  std::cout << ".";
  std::cout.flush();

  // -------------------------------

  remove (OUTPUT_FILE_NAME);

#ifndef ONLY_MMAP_TEST

  OPEN_FP_OUT;
  MEASURE_WITH_NO_ARG (C_01__functions_getc_putc);
  CLOSE_FP_OUT;

  OPEN_FP_OUT;
  MEASURE_WITH_NO_ARG (C_02__functions_fgetc_fputc);
  CLOSE_FP_OUT;

  OPEN_FP_OUT;
  MEASURE_WITH_NO_ARG (C_03__functions_fread_fwrite__const_buf);
  CLOSE_FP_OUT;

  OPEN_FP_OUT;
  MEASURE_WITH_NO_ARG (C_04__functions_fread_fwrite__max_buf);
  CLOSE_FP_OUT;

#endif

#ifdef __unix

  OPEN_FD_OUT;
  MEASURE_WITH_NO_ARG (C_UNIX_01__mmap_write);
  CLOSE_FD_OUT;
  
  OPEN_FD_OUT;
  MEASURE_WITH_NO_ARG (C_UNIX_02__mmap_memcpy);
  CLOSE_FD_OUT;

#endif

#ifndef ONLY_MMAP_TEST

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_01__operators_in_out);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_02__methods_sbumpc_sputc);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_03__method_sbumpc__op_out);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_04__method_rdbuf__op_out);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_05__methods_cpp_read_write__const_buf);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_06__methods_cpp_read_write_oss__const_buf);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_07__methods_cpp_readsome_write__const_buf);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_08__methods_cpp_read_write__max_buf);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_09__function_getline__ostringstream);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_10__function_getline__string);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_11__method_ifstream_getline);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_12__methods_ifstream_get_put);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_13__method_ifstream_get);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_14__method_ifstream_get__const_buf);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_15__method_ifstream_get__streambuf);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_16__iostream_iterators__copy);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_17__iostream_iterators__string);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_18__iostreambuf_iterators__copy);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_19__iostreambuf_iterators__transform);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_20__iostreambuf_iterators__string);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_21__vector__copy);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_22__vector_push_back);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_23__vector__cpp_read);
  CLOSE_FS_OUT;

  OPEN_FS_OUT;
  MEASURE_WITH_NO_ARG (CPP_24__string__cpp_read);
  CLOSE_FS_OUT;

#endif


  // -------------------------------
  // std::cerr << "\t     Test-" << s_numberOfTests << " finished" << std::endl;

  // -------------------------------

  ASSERT (s_pMbuffer != NULL);
  delete[] s_pMbuffer;
  s_pMbuffer = NULL;

  s_fsIn.clear();
  s_fsIn.close();
  ASSERT (!s_fsIn.is_open());

  s_fsOut.clear();
  s_fsOut.close();
  ASSERT (!s_fsOut.is_open());

int rc;

#ifdef __unix

  rc = close (s_fdIn);
  ASSERT (rc == 0);

#endif

  clearerr(s_fpIn);
  rc = fclose(s_fpIn);
  ASSERT (rc == 0);

}

// ------------
void show (std::size_t no_of_tests)
{
clock_t units;
clock_t sum;
#define THRESHOLD  0.2
const std::size_t   threshold = std::size_t(no_of_tests * THRESHOLD);

  ASSERT ((threshold * 2) <= no_of_tests);

  std::cout << std::endl;
  ASSERT (s_funcNames.size() == s_usedTime.size());

  for (std::size_t i = 0; i < s_funcNames.size(); i++)
  {
    sum = 0;
    ASSERT (no_of_tests == s_usedTime[i].size());
    for (std::size_t k = threshold; k < (s_usedTime[i].size() - threshold); k++)
    {
      sum += s_usedTime[i][k];
    }
    units = sum/(s_usedTime[i].size() - (threshold * 2));

    std::cout << std::setw(s_funcSetw)
         << std::left
         << s_funcNames[i]
         << " : "
         << std::setw(6)
         << std::right
         << units
         << " units"
         << " (";
    std::cout.setf(std::ios::fixed, std::ios::floatfield);
    std::cout << std::setprecision  (3)
         << (float(units)/float(CLOCKS_PER_SEC))
         << " secs)"
         << std::endl;
  }

}

// ------------
void run (std::size_t no_of_runs, std::size_t no_of_tests, std::size_t no_of_repetitions)
{
  for (std::size_t i = 0; i < no_of_runs; i++)
  {
    s_numberOfRuns = i + 1;
    s_funcNames.clear();
    s_usedTime.clear();

    // ----------------------
    std::cout << std::endl << std::endl << "   Run-" << (i + 1) << " of " << no_of_runs << " : Started ";
    std::cout.flush();
    for (std::size_t k = 0; k < no_of_tests; k++) 
    {
      s_numberOfTests = k + 1;
      measure (no_of_repetitions);
    }
    show (no_of_tests);
    std::cout << "   Run-" << (i + 1) << " of " << no_of_runs << " : Finished"<< std::endl << std::endl;
  }
}


// ------------
int main(int argc, char** argv)
{

  std::cout << std::endl;
  std::cout << std::string (std::string (PROGRAM_NAME).size(), '=') << std::endl;
  std::cout << PROGRAM_NAME << std::endl;
  std::cout << PROGRAM_VERSION << std::endl;
  std::cout << std::string (std::string (PROGRAM_NAME).size(), '=') << std::endl;
  // --------------------------

  std::cout << std::endl;
  std::cout << std::endl;
  show_env_info();

  std::cout << std::endl;
  std::cout << "\tYOUR COMMAND LINE : ";
std::string exe_name (argv[0]);
  std::cout << exe_name.substr (exe_name.find_last_of ("/\\") + 1) << " ";
  for (long i = 1; i < argc; i++) std::cout << argv[i] << " ";
  std::cout << std::endl;
  std::cout << std::endl;

  if (!(argc >= 4))
  {
    std::cout << "\tUSAGE : "
         << argv[0]
         << " "
         << "<File size> <No. of tests> <No. of repetitions> [<No. of runs>]"
         << std::endl;
    return 1;
  }
  ASSERT (argc >= 4);

  s_userDefinedFileSize = atoi (argv[1]);
  ASSERT (s_userDefinedFileSize > 0);

const std::size_t no_of_tests (atoi (argv[2]));
  ASSERT (no_of_tests > 0);

const std::size_t no_of_repetitions (atoi (argv[3]));
  ASSERT (no_of_repetitions > 0);

const std::size_t no_of_runs (((argc > 4) ? atoi (argv[4]) : 1));
  ASSERT (no_of_runs > 0);

  std::cout << "\t### File size             : " << s_userDefinedFileSize << std::endl;
  std::cout << "\t### Number of runs        : " << no_of_runs << std::endl;
  std::cout << "\t### Number of tests       : " << no_of_tests << std::endl;
  std::cout << "\t### Number of repetitions : " << no_of_repetitions << std::endl;
  std::cout << "\t### CLOCKS_PER_SEC        : " << CLOCKS_PER_SEC << std::endl;
  std::cout << std::endl;

  // -----------------------------
  run (no_of_runs, no_of_tests, no_of_repetitions);

  return 0;

}

Reply all
Reply to author
Forward
0 new messages