Download | Plain Text | Line Numbers


/**
 * @module cmem
 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
 * @brief  Memory template and memory definition for CCPU
 * @date   26.05.2009
 */
 
#ifndef CMEM_H
#define CMEM_H 1
 
#include <vector>
#include <istream>
#include <sstream>
#include <stdexcept>
#ifdef DEBUG
# include <iostream>
# include <iomanip>
#endif
 
/**
 * @class CMemError
 *
 * Exception thrown by implemententations of CMem
 */
class CMemError
 : public std::invalid_argument
{
  public:
    /**
     * @method CMemError
     * @brief  Default exception ctor
     * @param  what  message to pass along
     * @return -
     * @globalvars none
     * @exception  none
     * @pre  none
     * @post none
     */
    CMemError(const std::string& what)
      : std::invalid_argument(what)
    {}
};
 
/**
 * @class CMem
 *
 * Extends std::vector template for use as memory for CCPU.
 */
template <class T>
class CMem
  : public std::vector<T>
{
  typedef std::vector<T> super;
  typedef typename super::iterator iterator;
  using super::size;
  using super::begin;
  using super::end;
 
  public:
    /**
     * @method initialize
     * @brief  initialize the vector with the content of istream. istream is
     *         read per line. empty lines will add unitialized elements.
     * @param  in        inputstream to read from
     * @param  datatype  reference instance of datatype to copy from
     * @return void
     * @globalvars none
     * @exception  CMemError
     * @pre  none
     * @post none
     */
    void initialize(std::istream& in, T& datatype)
    {
      if (!in.good())
        return;
 
      std::string line;
      unsigned i = 0;
      while (!in.eof() && in.good())
      {
        ++i;
        std::getline(in, line);
 
        /* skip last line if it's empty */
        if (line.empty() && in.eof())
          break;
 
        T value(datatype);
        if (!line.empty())
        {
          /* simple boost::lexical_cast replacement */
          std::stringstream interpreter;
          if(!(interpreter << line && interpreter >> value && interpreter.get() == std::char_traits<char>::eof()))
          {
            std::stringstream sstr;
            sstr << "Unable to convert input (line " << i << ") to datatype";
            throw CMemError(sstr.str());
          }
        }
 
        push_back(value);
      }
    }
 
#if DEBUG
    /**
     * @method dump
     * @brief  dumps contents of vector to outputstream
     * @param  out  outputstream to write to
     * @return void
     * @globalvars none
     * @exception  none
     * @pre  none
     * @post none
     */
    void dump(std::ostream& out)
    {
      out << "[MEMORY DUMP]" << std::endl;
      unsigned i = 0;
      for(iterator it = begin(); it != end(); ++it)
      {
        out << "[" << std::setw(4) << std::setfill('0') << i << "]  "
            << *it << std::endl;
        ++i;
      }
    }
#endif
};
 
#endif
 
/* vim: set et sw=2 ts=2: */