#ifndef FUNC_REC_H
#define FUNC_REC_H

#include <string>
#include <ostream>
#include <algorithm>

namespace mem {

template <int bin_count>
class FuncRecord
{
public:
  FuncRecord();
  FuncRecord(const std::string& name,int id, unsigned long addr);

  void accum(int value);

  int binCount() const { return bin_count; }
  unsigned long address() const { return addr_; }
  const std::string& name() const { return name_; }
  int totalEntries() const { return total_; }
  int id() const { return id_; }

  void print(std::ostream&) const;

private:
  int hist_[bin_count+1]; // overflows in last bin
  int total_;
  int id_;
  unsigned long addr_;
  std::string name_;
};

template <int bin_count>
std::ostream& operator<<(std::ostream& ost, const FuncRecord<bin_count>& f)
{
  f.print(ost);
  return ost;
}

template <int bin_count>
void FuncRecord<bin_count>::accum(int value)
{
  if(value > bin_count) value = bin_count;
  ++hist_[value];
  ++total_;
}

template <int bin_count>
FuncRecord<bin_count>::FuncRecord(const std::string& name,
				       int id, unsigned long addr)
    : total_()
    , id_(id)
    , addr_(addr)
    , name_(name)
{
  std::fill(hist_+0,hist_+bin_count+1,0);
}

template <int bin_count>
FuncRecord<bin_count>::FuncRecord():
  id_(),addr_(),total_(),name_("None")
{
  std::fill(hist_+0,hist_+bin_count+1,0);
}

template <int bin_count>
void FuncRecord<bin_count>::print(std::ostream& ost) const
{
  ost << id_ << " " << (void*)addr_ << " " << total_ << " "
      << name_ << " ";
  std::copy(hist_+0,hist_+bin_count+1,std::ostream_iterator<int>(ost," "));
}

}
#endif
