// ===========================================================================
//
// 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;
}