text: /*
   * Memory.h
   *
   */
  
  #ifndef GC_MEMORY_H_
  #define GC_MEMORY_H_
  
  #include <vector>
  #include <sstream>
  #include <iostream>
  #include <typeinfo>
  using namespace std;
  
  #include "Tools/Exceptions.h"
  #include "Clear.h"
  #include "config.h"
  
  class NoMemory
  {
  };
  
  namespace GC
  {
  
  template <class T>
  class Memory : public vector<T>
  {
  public:
      void resize(size_t size, const char* name = "");
      void resize_min(size_t size, const char* name = "");
      void check_index(Integer index) const;
      T& operator[] (Integer i);
      const T& operator[] (Integer i) const;
      size_t capacity_in_bytes() const { return this->capacity() * sizeof(T); }
  };
  
  template <class T>
  inline void Memory<T>::check_index(Integer index) const
  {
      (void)index;
  #ifdef CHECK_SIZE
  	size_t i = index.get();
      if (i >= vector<T>::size())
      {
          stringstream ss;
          ss << T::type_string() << " memory overflow: " << i << "/" << vector<T>::size();
          throw Processor_Error(ss.str());
      }
  #endif
  #ifdef DEBUG_MEMORY
      cout << typeid(T).name() << " at " << this << " index " << i << ": "
              << vector<T>::operator[](i) << endl;
  #endif
  }
  
  template <class T>
  inline T& Memory<T>::operator[] (Integer i)
  {
      check_index(i);
      return vector<T>::operator[](i.get());
  }
  
  template <class T>
  inline const T& Memory<T>::operator[] (Integer i) const
  {
      check_index(i);
      return vector<T>::operator[](i.get());
  }
  
  template <class T>
  inline void Memory<T>::resize(size_t size, const char* name)
  {
      (void) name;
  #ifdef DEBUG_MEMORY
      if (size > 1000)
          cerr << "Resizing " << T::type_string() << " " << name << " to " << size << endl;
  #endif
      vector<T>::resize(size);
  }
  
  template <class T>
  inline void Memory<T>::resize_min(size_t size, const char* name)
  {
      if (this->size() < size)
          resize(size, name);
  }
  
  template <class T>
  inline ostream& operator<<(ostream& s, const Memory<T>& memory)
  {
      for (auto& x : memory)
          x.output(s, false);
      return s;
  }
  
  } /* namespace GC */
  
  #endif /* GC_MEMORY_H_ */
  