Tags: code

code

Readable exceptions fun

#include <stdexcept>
#include <iostream>

class Class
{
public:
   struct Exception
   {
      struct Any : public std::exception {};
      struct CannotConstruct : public Any {};
   };

   Class() { throw Exception::CannotConstruct(); }
};

void iKnowAboutClassAndItsConstruction (void)
{
   try
   {
      Class();
   }
   catch (Class::Exception::CannotConstruct&)
   {
      std::cout << "got Class::Exception::CannotConstruct.\n";
      // Do something... or:
      throw;
   }
}

void iKnowAboutClasses (void)
{
   try
   {
      // do something useful and specific with Class(es):
      iKnowAboutClassAndItsConstruction();
      // ...
      // ...
   }
   catch (Class::Exception::Any&)
   {
      std::cout << "got some Class::Exception.\n";  
      // Do something... or:
      throw;
   }
}

void main (void)
{
   try
   {
      // let's do something with Class(es):
      iKnowAboutClasses();
   }
   // main -- don't care about any specific exceptions but standard:
   catch (std::exception&) { std::cout << "got std::exception.\n";    }
   catch (...)             { std::cout << "got unknown exception.\n"; }
}
code

File reading contest

Sample output:

>streamReadingContest_StlPort.exe 50mb
reading 50mb...
reserveDistanceCopyStreamItersViaInserter 0.4
seekAndLoadArray 0.75
seekAndLoadVector 0.8
seekAndLoadVectorReserve 0.8
putInStringStream 3.8
assignToStreamItersInterval 0.8
reserveAssignToStreamItersInterval 0.3
copyStreamItersViaInserter 0.75

>streamReadingContest_home.exe 50mb
reading 50mb...
reserveDistanceCopyStreamItersViaInserter 0.5
seekAndLoadArray 2.95
seekAndLoadVector 2.95
seekAndLoadVectorReserve 3
putInStringStream 4.45
assignToStreamItersInterval 3.65
reserveAssignToStreamItersInterval 0.45
copyStreamItersViaInserter 3.25


Looks like the winner is reserveAssignToStreamItersInterval. =)

#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <ctime>

typedef std::string FileName;


typedef void (LoadFunc) (const FileName& fileName, std::string& result);

void seekAndLoadArray (const FileName& fileName, std::string& result)
{
   std::ifstream inFile( fileName.c_str(), std::ios::binary );

   inFile.seekg( 0, std::ios_base::end );
   unsigned long fileSize = inFile.tellg();
   inFile.seekg( 0, std::ios_base::beg );

   char* buf = new char[ fileSize ];
   inFile.read(   buf, fileSize );
   result.assign( buf, buf + fileSize );
   delete[] buf;
}


void seekAndLoadVector (const FileName& fileName, std::string& result)
{
   std::ifstream inFile( fileName.c_str(), std::ios::binary );

   inFile.seekg( 0, std::ios_base::end );
   unsigned long fileSize = inFile.tellg();
   inFile.seekg( 0, std::ios_base::beg );

   std::vector<char> buf( fileSize );
                     buf.resize( fileSize );

   inFile.read( &buf[0], fileSize );
   result.assign( buf.begin(), buf.end() );
}


void seekAndLoadVectorReserve (const FileName& fileName, std::string& result)
{
   std::ifstream inFile( fileName.c_str(), std::ios::binary );

   inFile.seekg( 0, std::ios_base::end );
   unsigned long fileSize = inFile.tellg();
   inFile.seekg( 0, std::ios_base::beg );

   std::vector<char> buf( fileSize );
                     buf.resize( fileSize );

   inFile.read( &buf[0], fileSize );
   result.reserve( fileSize );
   result.assign( buf.begin(), buf.end() );
}


void putInStringStream (const FileName& fileName, std::string& result)
{
   std::ifstream inFile( fileName.c_str(), std::ios::binary );
   std::ostringstream resultStringStream;

   char ch;
   while (inFile.get( ch ))
   {
      resultStringStream.put( ch );
   }

   result = resultStringStream.str();
}


void assignToStreamItersInterval (const FileName& fileName, std::string& result)
{
   std::ifstream inFile (fileName.c_str(), std::ios::binary);
   std::istreambuf_iterator<char> b( inFile ), e;
   result.assign( b, e );
}


void reserveAssignToStreamItersInterval (const FileName& fileName, std::string& result)
{
   std::ifstream inFile (fileName.c_str(), std::ios::binary);
   std::istreambuf_iterator<char> b( inFile ), e;
   result.reserve( std::distance( b, e ) );
   result.assign( b, e );
}


void copyStreamItersViaInserter (const FileName& fileName, std::string& result)
{
   std::ifstream inFile (fileName.c_str(), std::ios::binary);
   std::istreambuf_iterator<char> b( inFile ), e;
   result.clear();
   std::copy( b, e, std::back_inserter( result ) );
}


void reserveDistanceCopyStreamItersViaInserter (const FileName& fileName, std::string& result)
{
   std::ifstream inFile (fileName.c_str(), std::ios::binary);
   std::istreambuf_iterator<char> b( inFile ), e;
   result.resize( std::distance( b, e ) );
   std::copy( b, e, result.begin() );
}


FileName fileName;


void testLoad (LoadFunc loader, const std::string& loaderName)
{
   const int NumTests = 20;
   double acc = 0.0;
   std::cout << loaderName << " ";

   for (int i = 0; i < NumTests; ++i)
   {
      std::string result;

      time_t start = std::time( 0 );
      loader( fileName, result );
      time_t end = std::time( 0 );

      acc += end - start;
   }
   std::cout << acc / NumTests << "\n";
}


void main (int argc, char **argv)
{
   if (argc > 1)
   {
      fileName = argv[1];

      std::cout << "reading " << fileName << "...\n";

      testLoad( reserveDistanceCopyStreamItersViaInserter, "reserveDistanceCopyStreamItersViaInserter" );
      testLoad( seekAndLoadArray, "seekAndLoadArray" );
      testLoad( seekAndLoadVector, "seekAndLoadVector" );
      testLoad( seekAndLoadVectorReserve, "seekAndLoadVectorReserve" );
      testLoad( putInStringStream, "putInStringStream" );
      testLoad( assignToStreamItersInterval, "assignToStreamItersInterval" );
      testLoad( reserveAssignToStreamItersInterval, "reserveAssignToStreamItersInterval" );
      testLoad( copyStreamItersViaInserter, "copyStreamItersViaInserter" );
   }
   else
   {
      std::cout << "Expected filename as a parameter!";
   }
}