<Release> Simple C/C++ Perfometer: Copying Files (Versions 5.1)

23 views
Skip to first unread message

Alex Vinokur

unread,
Nov 20, 2013, 7:54:16 AM11/20/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.1"
//
//  -------------------------------------
//
//  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
//  http://www.linkedin.com/in/alexvinokur
//
// ===========================================================================

 

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
//    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 <map>
#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 showEnvInfo();

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 closeFsOut (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 i_totalFullRows = 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 (const std::size_t i_noOfRepetitions);
static void showElapsedTime (const std::size_t i_noOfTests);
static void showSortedElapsedTime (const std::size_t i_noOfTests);
static void run (const std::size_t i_noOfRuns, const std::size_t i_noOfTests, std::size_t i_noOfRepetitions);


// ========================================
// ====== 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:
    // http://predef.sourceforge.net/precomp.html
    // ------------------------------------------

    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);
    oss << std::setfill ('0');
    oss << 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 showEnvInfo()
// -----------------------------
{
 
std::ostringstream ossCompilationMachine;
  ossCompilationMachine << "Compilation Machine:  ";
  ossCompilationMachine << getCompilationMachineName();
 
std::ostringstream ossRunMachine;
  ossRunMachine << "Run Machine:  ";
  ossRunMachine << getRunMachineName(true);
          
std::ostringstream ossCompiler;
  ossCompiler << "Compiler:  ";
  ossCompiler << 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 (std::string(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 CLOSE_FP_OUT closeFpOut (__LINE__)

#define OPEN_FD_OUT  openFdOut  (__LINE__)
#define CLOSE_FD_OUT closeFdOut (__LINE__)

#define OPEN_FS_OUT  openFsOut  (__LINE__)
#define CLOSE_FS_OUT closeFsOut (__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 closeFsOut (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 i_totalFullRows)
// ---------------------------------------
{
  ASSERT (i_totalFullRows > 0);
  if (s_userDefinedFileSize < i_totalFullRows)
  {
    i_totalFullRows = s_userDefinedFileSize;
  }
  ASSERT (i_totalFullRows <= 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/i_totalFullRows);


#define START_CH 0
char ch = START_CH;

std::size_t counter = 0;
  for (std::size_t row_no = 0; row_no < i_totalFullRows; 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 < i_noOfRepetitions; 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 (const std::size_t i_noOfRepetitions)
{
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 showElapsedTime (const std::size_t i_noOfTests)
{
clock_t units;
clock_t sum;
#define THRESHOLD  0.2
const std::size_t   threshold = std::size_t(i_noOfTests * THRESHOLD);

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

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

  std::cout << "=== Ordered According Function Name ==="
           << std::endl;
  for (std::size_t i = 0; i < s_funcNames.size(); i++)
  {
    sum = 0;
    ASSERT (i_noOfTests == 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(10)
         << 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 showSortedElapsedTime (const std::size_t i_noOfTests)
{
clock_t units;
clock_t sum;
#define THRESHOLD  0.2
const std::size_t   threshold = std::size_t(i_noOfTests * THRESHOLD);

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

  std::cout << std::endl;
  ASSERT (s_funcNames.size() == s_usedTime.size());
 
  std::multimap<clock_t, std::string> mmapTimes;

  std::cout << "=== Ordered According Elapsed Time ==="
           << std::endl;
  for (std::size_t i = 0; i < s_funcNames.size(); i++)
  {
    sum = 0;
    ASSERT (i_noOfTests == 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));
   
    mmapTimes.insert(std::make_pair(units, s_funcNames[i]));

    /*
    std::cout << std::setw(s_funcSetw)
         << std::left
         << s_funcNames[i]
         << " : "
         << std::setw(10)
         << 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;
    */
  }
 
  std::multimap<clock_t, std::string>::const_iterator iter;
  for (iter = mmapTimes.begin();
       iter != mmapTimes.end();
       iter++
       )
  {
    std::cout << std::setw(s_funcSetw)
         << std::left
         << iter->second
         << " : "
         << std::setw(10)
         << std::right
         << iter->first
         << " 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 (const std::size_t i_noOfRuns, std::size_t i_noOfTests, const std::size_t i_noOfRepetitions)
{
  for (std::size_t i = 0; i < i_noOfRuns; i++)
  {
    s_numberOfRuns = i + 1;
    s_funcNames.clear();
    s_usedTime.clear();

    // ----------------------
    std::cout << std::endl << std::endl << "   Run-" << (i + 1) << " of " << i_noOfRuns << " : Started ";
    std::cout.flush();
    for (std::size_t k = 0; k < i_noOfTests; k++)
    {
      s_numberOfTests = k + 1;
      measure (i_noOfRepetitions);
    }
    showElapsedTime (i_noOfTests);
    showSortedElapsedTime (i_noOfTests);
    std::cout << "   Run-" << (i + 1) << " of " << i_noOfRuns << " : 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;
  showEnvInfo();

  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 i_noOfTests (atoi (argv[2]));
  ASSERT (i_noOfTests > 0);

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

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

  std::cout << "\t### File size             : " << s_userDefinedFileSize << std::endl;
  std::cout << "\t### Number of runs        : " << i_noOfRuns << std::endl;
  std::cout << "\t### Number of tests       : " << i_noOfTests << std::endl;
  std::cout << "\t### Number of repetitions : " << i_noOfRepetitions << std::endl;
  std::cout << "\t### CLOCKS_PER_SEC        : " << CLOCKS_PER_SEC << std::endl;
  std::cout << std::endl;

  // -----------------------------
  run (i_noOfRuns, i_noOfTests, i_noOfRepetitions);

  return 0;

}

Reply all
Reply to author
Forward
0 new messages