/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** @file
 * Declaration of Statistics objects.
 */

/**
* @todo
*
* Generalized N-dimensinal vector
* documentation
* key stats
* interval stats
*   -- these both can use the same function that prints out a
*   specific set of stats
* VectorStandardDeviation totals
* Document Namespaces
*/
#ifndef __BASE_STATISTICS_HH__
#define __BASE_STATISTICS_HH__

#include <algorithm>
#include <cassert>
#include <cmath>
#include <functional>
#include <iosfwd>
#include <sstream>
#include <string>
#include <vector>

#include "base/cprintf.hh"
#include "base/intmath.hh"
#include "base/refcnt.hh"
#include "base/str.hh"
#include "base/stats/bin.hh"
#include "base/stats/flags.hh"
#include "base/stats/visit.hh"
#include "base/stats/types.hh"
#include "config/stats_binning.hh"
#include "sim/host.hh"

class Callback;

/** The current simulated cycle. */
extern Tick curTick;

/* A namespace for all of the Statistics */
namespace Stats {

/* Contains the statistic implementation details */
//////////////////////////////////////////////////////////////////////
//
// Statistics Framework Base classes
//
//////////////////////////////////////////////////////////////////////
struct StatData
{
    /** The name of the stat. */
    std::string name;
    /** The description of the stat. */
    std::string desc;
    /** The formatting flags. */
    StatFlags flags;
    /** The display precision. */
    int precision;
    /** A pointer to a prerequisite Stat. */
    const StatData *prereq;
    /**
     * A unique stat ID for each stat in the simulator.
     * Can be used externally for lookups as well as for debugging.
     */
    int id;

    StatData();
    virtual ~StatData();

    /**
     * @return true if the stat is binned.
     */
    virtual bool binned() const = 0;

    /**
     * Reset the corresponding stat to the default state.
     */
    virtual void reset() = 0;

    /**
     * @return true if this stat has a value and satisfies its
     * requirement as a prereq
     */
    virtual bool zero() const = 0;

    /**
     * Check that this stat has been set up properly and is ready for
     * use
     * @return true for success
     */
    virtual bool check() const = 0;
    bool baseCheck() const;

    /**
     * Visitor entry for outputing statistics data
     */
    virtual void visit(Visit &visitor) = 0;

    /**
     * Checks if the first stat's name is alphabetically less than the second.
     * This function breaks names up at periods and considers each subname
     * separately.
     * @param stat1 The first stat.
     * @param stat2 The second stat.
     * @return stat1's name is alphabetically before stat2's
     */
    static bool less(StatData *stat1, StatData *stat2);
};

class ScalarData : public StatData
{
  public:
    virtual Counter value() const = 0;
    virtual Result result() const = 0;
    virtual Result total() const = 0;
    virtual void visit(Visit &visitor) { visitor.visit(*this); }
};

template <class Stat>
class ScalarStatData : public ScalarData
{
  protected:
    Stat &s;

  public:
    ScalarStatData(Stat &stat) : s(stat) {}

    virtual bool binned() const { return s.binned(); }
    virtual bool check() const { return s.check(); }
    virtual Counter value() const { return s.value(); }
    virtual Result result() const { return s.result(); }
    virtual Result total() const { return s.total(); }
    virtual void reset() { s.reset(); }
    virtual bool zero() const { return s.zero(); }
};

struct VectorData : public StatData
{
    /** Names and descriptions of subfields. */
    mutable std::vector<std::string> subnames;
    mutable std::vector<std::string> subdescs;

    virtual size_t size() const  = 0;
    virtual const VCounter &value() const = 0;
    virtual const VResult &result() const = 0;
    virtual Result total() const  = 0;
    void update()
    {
        if (!subnames.empty()) {
            int s = size();
            if (subnames.size() < s)
                subnames.resize(s);

            if (subdescs.size() < s)
                subdescs.resize(s);
        }
    }
};

template <class Stat>
class VectorStatData : public VectorData
{
  protected:
    Stat &s;
    mutable VCounter cvec;
    mutable VResult rvec;

  public:
    VectorStatData(Stat &stat) : s(stat) {}

    virtual bool binned() const { return s.binned(); }
    virtual bool check() const { return s.check(); }
    virtual bool zero() const { return s.zero(); }
    virtual void reset() { s.reset(); }

    virtual size_t size() const { return s.size(); }
    virtual VCounter &value() const
    {
        s.value(cvec);
        return cvec;
    }
    virtual const VResult &result() const
    {
        s.result(rvec);
        return rvec;
    }
    virtual Result total() const { return s.total(); }
    virtual void visit(Visit &visitor)
    {
        update();
        s.update(this);
        visitor.visit(*this);
    }
};

struct DistDataData
{
    Counter min_val;
    Counter max_val;
    Counter underflow;
    Counter overflow;
    VCounter cvec;
    Counter sum;
    Counter squares;
    Counter samples;

    Counter min;
    Counter max;
    Counter bucket_size;
    int size;
    bool fancy;
};

struct DistData : public StatData
{
    /** Local storage for the entry values, used for printing. */
    DistDataData data;
};

template <class Stat>
class DistStatData : public DistData
{
  protected:
    Stat &s;

  public:
    DistStatData(Stat &stat) : s(stat) {}

    virtual bool binned() const { return s.binned(); }
    virtual bool check() const { return s.check(); }
    virtual void reset() { s.reset(); }
    virtual bool zero() const { return s.zero(); }
    virtual void visit(Visit &visitor)
    {
        s.update(this);
        visitor.visit(*this);
    }
};

struct VectorDistData : public StatData
{
    std::vector<DistDataData> data;

   /** Names and descriptions of subfields. */
    mutable std::vector<std::string> subnames;
    mutable std::vector<std::string> subdescs;

    /** Local storage for the entry values, used for printing. */
    mutable VResult rvec;

    virtual size_t size() const = 0;
    void update()
    {
        int s = size();
        if (subnames.size() < s)
            subnames.resize(s);

        if (subdescs.size() < s)
            subdescs.resize(s);
    }
};

template <class Stat>
class VectorDistStatData : public VectorDistData
{
  protected:
    Stat &s;
    typedef typename Stat::bin_t bin_t;

  public:
    VectorDistStatData(Stat &stat) : s(stat) {}

    virtual bool binned() const { return bin_t::binned; }
    virtual bool check() const { return s.check(); }
    virtual void reset() { s.reset(); }
    virtual size_t size() const { return s.size(); }
    virtual bool zero() const { return s.zero(); }
    virtual void visit(Visit &visitor)
    {
        update();
        s.update(this);
        visitor.visit(*this);
    }
};

struct Vector2dData : public StatData
{
    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;
    std::vector<std::string> y_subnames;

    /** Local storage for the entry values, used for printing. */
    mutable VCounter cvec;
    mutable int x;
    mutable int y;

    void update()
    {
        if (subnames.size() < x)
            subnames.resize(x);
    }
};

template <class Stat>
class Vector2dStatData : public Vector2dData
{
  protected:
    Stat &s;
    typedef typename Stat::bin_t bin_t;

  public:
    Vector2dStatData(Stat &stat) : s(stat) {}

    virtual bool binned() const { return bin_t::binned; }
    virtual bool check() const { return s.check(); }
    virtual void reset() { s.reset(); }
    virtual bool zero() const { return s.zero(); }
    virtual void visit(Visit &visitor)
    {
        update();
        s.update(this);
        visitor.visit(*this);
    }
};


class DataAccess
{
  protected:
    StatData *find() const;
    void map(StatData *data);

    StatData *statData();
    const StatData *statData() const;

    void setInit();
    void setPrint();
};

template <class Parent, class Child, template <class> class Data>
class Wrap : public Child
{
  protected:
    Parent &self() { return *reinterpret_cast<Parent *>(this); }

  protected:
    Data<Child> *statData()
    {
        StatData *__data = DataAccess::statData();
        Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
        assert(ptr);
        return ptr;
    }

  public:
    const Data<Child> *statData() const
    {
        const StatData *__data = DataAccess::statData();
        const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
        assert(ptr);
        return ptr;
    }

  protected:
    /**
     * Copy constructor, copies are not allowed.
     */
    Wrap(const Wrap &stat);
    /**
     * Can't copy stats.
     */
    void operator=(const Wrap &);

  public:
    Wrap()
    {
      map(new Data<Child>(*this));
    }

    /**
     * Set the name and marks this stat to print at the end of simulation.
     * @param name The new name.
     * @return A reference to this stat.
     */
    Parent &name(const std::string &_name)
    {
        Data<Child> *data = this->statData();
        data->name = _name;
        this->setPrint();
        return this->self();
    }

    /**
     * Set the description and marks this stat to print at the end of
     * simulation.
     * @param desc The new description.
     * @return A reference to this stat.
     */
    Parent &desc(const std::string &_desc)
    {
        this->statData()->desc = _desc;
        return this->self();
    }

    /**
     * Set the precision and marks this stat to print at the end of simulation.
     * @param p The new precision
     * @return A reference to this stat.
     */
    Parent &precision(int _precision)
    {
        this->statData()->precision = _precision;
        return this->self();
    }

    /**
     * Set the flags and marks this stat to print at the end of simulation.
     * @param f The new flags.
     * @return A reference to this stat.
     */
    Parent &flags(StatFlags _flags)
    {
        this->statData()->flags |= _flags;
        return this->self();
    }

    /**
     * Set the prerequisite stat and marks this stat to print at the end of
     * simulation.
     * @param prereq The prerequisite stat.
     * @return A reference to this stat.
     */
    template <class Stat>
    Parent &prereq(const Stat &prereq)
    {
        this->statData()->prereq = prereq.statData();
        return this->self();
    }
};

template <class Parent, class Child, template <class Child> class Data>
class WrapVec : public Wrap<Parent, Child, Data>
{
  public:
    // The following functions are specific to vectors.  If you use them
    // in a non vector context, you will get a nice compiler error!

    /**
     * Set the subfield name for the given index, and marks this stat to print
     * at the end of simulation.
     * @param index The subfield index.
     * @param name The new name of the subfield.
     * @return A reference to this stat.
     */
    Parent &subname(int index, const std::string &name)
    {
        std::vector<std::string> &subn = this->statData()->subnames;
        if (subn.size() <= index)
            subn.resize(index + 1);
        subn[index] = name;
        return this->self();
    }

    /**
     * Set the subfield description for the given index and marks this stat to
     * print at the end of simulation.
     * @param index The subfield index.
     * @param desc The new description of the subfield
     * @return A reference to this stat.
     */
    Parent &subdesc(int index, const std::string &desc)
    {
        std::vector<std::string> &subd = this->statData()->subdescs;
        if (subd.size() <= index)
            subd.resize(index + 1);
        subd[index] = desc;

        return this->self();
    }

};

template <class Parent, class Child, template <class Child> class Data>
class WrapVec2d : public WrapVec<Parent, Child, Data>
{
  public:
    /**
     * @warning This makes the assumption that if you're gonna subnames a 2d
     * vector, you're subnaming across all y
     */
    Parent &ysubnames(const char **names)
    {
        Data<Child> *data = this->statData();
        data->y_subnames.resize(this->y);
        for (int i = 0; i < this->y; ++i)
            data->y_subnames[i] = names[i];
        return this->self();
    }
    Parent &ysubname(int index, const std::string subname)
    {
        Data<Child> *data = this->statData();
        assert(index < this->y);
        data->y_subnames.resize(this->y);
        data->y_subnames[index] = subname.c_str();
        return this->self();
    }
};

//////////////////////////////////////////////////////////////////////
//
// Simple Statistics
//
//////////////////////////////////////////////////////////////////////

/**
 * Templatized storage and interface for a simple scalar stat.
 */
struct StatStor
{
  public:
    /** The paramaters for this storage type, none for a scalar. */
    struct Params { };

  private:
    /** The statistic value. */
    Counter data;

  public:
    /**
     * Builds this storage element and calls the base constructor of the
     * datatype.
     */
    StatStor(const Params &) : data(Counter()) {}

    /**
     * The the stat to the given value.
     * @param val The new value.
     * @param p The paramters of this storage type.
     */
    void set(Counter val, const Params &p) { data = val; }
    /**
     * Increment the stat by the given value.
     * @param val The new value.
     * @param p The paramters of this storage type.
     */
    void inc(Counter val, const Params &p) { data += val; }
    /**
     * Decrement the stat by the given value.
     * @param val The new value.
     * @param p The paramters of this storage type.
     */
    void dec(Counter val, const Params &p) { data -= val; }
    /**
     * Return the value of this stat as its base type.
     * @param p The params of this storage type.
     * @return The value of this stat.
     */
    Counter value(const Params &p) const { return data; }
    /**
     * Return the value of this stat as a result type.
     * @param p The parameters of this storage type.
     * @return The value of this stat.
     */
    Result result(const Params &p) const { return (Result)data; }
    /**
     * Reset stat value to default
     */
    void reset() { data = Counter(); }

    /**
     * @return true if zero value
     */
    bool zero() const { return data == Counter(); }
};

/**
 * Templatized storage and interface to a per-cycle average stat. This keeps
 * a current count and updates a total (count * cycles) when this count
 * changes. This allows the quick calculation of a per cycle count of the item
 * being watched. This is good for keeping track of residencies in structures
 * among other things.
 * @todo add lateny to the stat and fix binning.
 */
struct AvgStor
{
  public:
    /** The paramaters for this storage type */
    struct Params
    {
        /**
         * The current count.  We stash this here because the current
         * value is not a binned value.
         */
        Counter current;
    };

  private:
    /** The total count for all cycles. */
    mutable Result total;
    /** The cycle that current last changed. */
    mutable Tick last;

  public:
    /**
     * Build and initializes this stat storage.
     */
    AvgStor(Params &p) : total(0), last(0) { p.current = Counter(); }

    /**
     * Set the current count to the one provided, update the total and last
     * set values.
     * @param val The new count.
     * @param p The parameters for this storage.
     */
    void set(Counter val, Params &p) {
        total += p.current * (curTick - last);
        last = curTick;
        p.current = val;
    }

    /**
     * Increment the current count by the provided value, calls set.
     * @param val The amount to increment.
     * @param p The parameters for this storage.
     */
    void inc(Counter val, Params &p) { set(p.current + val, p); }

    /**
     * Deccrement the current count by the provided value, calls set.
     * @param val The amount to decrement.
     * @param p The parameters for this storage.
     */
    void dec(Counter val, Params &p) { set(p.current - val, p); }

    /**
     * Return the current count.
     * @param p The parameters for this storage.
     * @return The current count.
     */
    Counter value(const Params &p) const { return p.current; }

    /**
     * Return the current average.
     * @param p The parameters for this storage.
     * @return The current average.
     */
    Result result(const Params &p) const
    {
        total += p.current * (curTick - last);
        last = curTick;
        return (Result)(total + p.current) / (Result)(curTick + 1);
    }

    /**
     * Reset stat value to default
     */
    void reset()
    {
        total = 0;
        last = curTick;
    }

    /**
     * @return true if zero value
     */
    bool zero() const { return total == 0.0; }
};

/**
 * Implementation of a scalar stat. The type of stat is determined by the
 * Storage template. The storage for this stat is held within the Bin class.
 * This allows for breaking down statistics across multiple bins easily.
 */
template <class Storage, class Bin>
class ScalarBase : public DataAccess
{
  public:
    /** Define the params of the storage class. */
    typedef typename Storage::Params params_t;
    /** Define the bin type. */
    typedef typename Bin::template Bin<Storage> bin_t;

  protected:
    /** The bin of this stat. */
    bin_t bin;
    /** The parameters for this stat. */
    params_t params;

  protected:
    /**
     * Retrieve the storage from the bin.
     * @return The storage object for this stat.
     */
    Storage *data() { return bin.data(params); }
    /**
     * Retrieve a const pointer to the storage from the bin.
     * @return A const pointer to the storage object for this stat.
     */
    const Storage *data() const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(*_params);
    }

  public:
    /**
     * Return the current value of this stat as its base type.
     * @return The current value.
     */
    Counter value() const { return data()->value(params); }

  public:
    /**
     * Create and initialize this stat, register it with the database.
     */
    ScalarBase()
    {
        bin.init(params);
    }

  public:
    // Common operators for stats
    /**
     * Increment the stat by 1. This calls the associated storage object inc
     * function.
     */
    void operator++() { data()->inc(1, params); }
    /**
     * Decrement the stat by 1. This calls the associated storage object dec
     * function.
     */
    void operator--() { data()->dec(1, params); }

    /** Increment the stat by 1. */
    void operator++(int) { ++*this; }
    /** Decrement the stat by 1. */
    void operator--(int) { --*this; }

    /**
     * Set the data value to the given value. This calls the associated storage
     * object set function.
     * @param v The new value.
     */
    template <typename U>
    void operator=(const U &v) { data()->set(v, params); }

    /**
     * Increment the stat by the given value. This calls the associated
     * storage object inc function.
     * @param v The value to add.
     */
    template <typename U>
    void operator+=(const U &v) { data()->inc(v, params); }

    /**
     * Decrement the stat by the given value. This calls the associated
     * storage object dec function.
     * @param v The value to substract.
     */
    template <typename U>
    void operator-=(const U &v) { data()->dec(v, params); }

    /**
     * Return the number of elements, always 1 for a scalar.
     * @return 1.
     */
    size_t size() const { return 1; }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    bool binned() const { return bin_t::binned; }

    bool check() const { return bin.initialized(); }

    /**
     * Reset stat value to default
     */
    void reset() { bin.reset(); }

    Counter value() { return data()->value(params); }

    Result result() { return data()->result(params); }

    Result total() { return result(); }

    bool zero() { return result() == 0.0; }

};

class ProxyData : public ScalarData
{
  public:
    virtual void visit(Visit &visitor) { visitor.visit(*this); }
    virtual bool binned() const { return false; }
    virtual std::string str() const { return to_string(value()); }
    virtual size_t size() const { return 1; }
    virtual bool zero() const { return value() == 0; }
    virtual bool check() const { return true; }
    virtual void reset() { }
};

template <class T>
class ValueProxy : public ProxyData
{
  private:
    T *scalar;

  public:
    ValueProxy(T &val) : scalar(&val) {}
    virtual Counter value() const { return *scalar; }
    virtual Result result() const { return *scalar; }
    virtual Result total() const { return *scalar; }
};

template <class T>
class FunctorProxy : public ProxyData
{
  private:
    T *functor;

  public:
    FunctorProxy(T &func) : functor(&func) {}
    virtual Counter value() const { return (*functor)(); }
    virtual Result result() const { return (*functor)(); }
    virtual Result total() const { return (*functor)(); }
};

class ValueBase : public DataAccess
{
  private:
    ProxyData *proxy;

  public:
    ValueBase() : proxy(NULL) { }
    ~ValueBase() { if (proxy) delete proxy; }

    template <class T>
    void scalar(T &value)
    {
        proxy = new ValueProxy<T>(value);
        setInit();
    }

    template <class T>
    void functor(T &func)
    {
        proxy = new FunctorProxy<T>(func);
        setInit();
    }

    Counter value() { return proxy->value(); }
    Result result() const { return proxy->result(); }
    Result total() const { return proxy->total(); };
    size_t size() const { return proxy->size(); }

    bool binned() const { return proxy->binned(); }
    std::string str() const { return proxy->str(); }
    bool zero() const { return proxy->zero(); }
    bool check() const { return proxy != NULL; }
    void reset() { }
};

//////////////////////////////////////////////////////////////////////
//
// Vector Statistics
//
//////////////////////////////////////////////////////////////////////
template <class Storage, class Bin>
class ScalarProxy;

/**
 * Implementation of a vector of stats. The type of stat is determined by the
 * Storage class. @sa ScalarBase
 */
template <class Storage, class Bin>
class VectorBase : public DataAccess
{
  public:
    /** Define the params of the storage class. */
    typedef typename Storage::Params params_t;
    /** Define the bin type. */
    typedef typename Bin::template VectorBin<Storage> bin_t;

  protected:
    /** The bin of this stat. */
    bin_t bin;
    /** The parameters for this stat. */
    params_t params;

  protected:
    /**
     * Retrieve the storage from the bin  for the given index.
     * @param index The vector index to access.
     * @return The storage object at the given index.
     */
    Storage *data(int index) { return bin.data(index, params); }
    /**
     * Retrieve a const pointer to the storage from the bin
     * for the given index.
     * @param index The vector index to access.
     * @return A const pointer to the storage object at the given index.
     */
    const Storage *data(int index) const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(index, *_params);
    }

  public:
    void value(VCounter &vec) const
    {
        vec.resize(size());
        for (int i = 0; i < size(); ++i)
            vec[i] = data(i)->value(params);
    }

    /**
     * Copy the values to a local vector and return a reference to it.
     * @return A reference to a vector of the stat values.
     */
    void result(VResult &vec) const
    {
        vec.resize(size());
        for (int i = 0; i < size(); ++i)
            vec[i] = data(i)->result(params);
    }

    /**
     * @return True is stat is binned.
     */
    bool binned() const { return bin_t::binned; }

    /**
     * Return a total of all entries in this vector.
     * @return The total of all vector entries.
     */
    Result total() const {
        Result total = 0.0;
        for (int i = 0; i < size(); ++i)
            total += data(i)->result(params);
        return total;
    }

    /**
     * @return the number of elements in this vector.
     */
    size_t size() const { return bin.size(); }

    bool zero() const
    {
        for (int i = 0; i < size(); ++i)
            if (data(i)->zero())
                return true;
        return false;
    }

    bool check() const { return bin.initialized(); }
    void reset() { bin.reset(); }

  public:
    VectorBase() {}

    /** Friend this class with the associated scalar proxy. */
    friend class ScalarProxy<Storage, Bin>;

    /**
     * Return a reference (ScalarProxy) to the stat at the given index.
     * @param index The vector index to access.
     * @return A reference of the stat.
     */
    ScalarProxy<Storage, Bin> operator[](int index);

    void update(StatData *data) {}
};

const StatData * getStatData(const void *stat);

/**
 * A proxy class to access the stat at a given index in a VectorBase stat.
 * Behaves like a ScalarBase.
 */
template <class Storage, class Bin>
class ScalarProxy
{
  public:
    /** Define the params of the storage class. */
    typedef typename Storage::Params params_t;
    /** Define the bin type. */
    typedef typename Bin::template VectorBin<Storage> bin_t;

  private:
    /** Pointer to the bin in the parent VectorBase. */
    bin_t *bin;
    /** Pointer to the params in the parent VectorBase. */
    params_t *params;
    /** The index to access in the parent VectorBase. */
    int index;
    /** Keep a pointer to the original stat so was can get data */
    void *stat;

  protected:
    /**
     * Retrieve the storage from the bin.
     * @return The storage from the bin for this stat.
     */
    Storage *data() { return bin->data(index, *params); }
    /**
     * Retrieve a const pointer to the storage from the bin.
     * @return A const pointer to the storage for this stat.
     */
    const Storage *data() const
    {
        bin_t *_bin = const_cast<bin_t *>(bin);
        params_t *_params = const_cast<params_t *>(params);
        return _bin->data(index, *_params);
    }

  public:
    /**
     * Return the current value of this stat as its base type.
     * @return The current value.
     */
    Counter value() const { return data()->value(*params); }

    /**
     * Return the current value of this statas a result type.
     * @return The current value.
     */
    Result result() const { return data()->result(*params); }

  public:
    /**
     * Create and initialize this proxy, do not register it with the database.
     * @param b The bin to use.
     * @param p The params to use.
     * @param i The index to access.
     */
    ScalarProxy(bin_t &b, params_t &p, int i, void *s)
        : bin(&b), params(&p), index(i), stat(s)  {}
    /**
     * Create a copy of the provided ScalarProxy.
     * @param sp The proxy to copy.
     */
    ScalarProxy(const ScalarProxy &sp)
        : bin(sp.bin), params(sp.params), index(sp.index), stat(sp.stat) {}
    /**
     * Set this proxy equal to the provided one.
     * @param sp The proxy to copy.
     * @return A reference to this proxy.
     */
    const ScalarProxy &operator=(const ScalarProxy &sp) {
        bin = sp.bin;
        params = sp.params;
        index = sp.index;
        stat = sp.stat;
        return *this;
    }

  public:
    // Common operators for stats
    /**
     * Increment the stat by 1. This calls the associated storage object inc
     * function.
     */
    void operator++() { data()->inc(1, *params); }
    /**
     * Decrement the stat by 1. This calls the associated storage object dec
     * function.
     */
    void operator--() { data()->dec(1, *params); }

    /** Increment the stat by 1. */
    void operator++(int) { ++*this; }
    /** Decrement the stat by 1. */
    void operator--(int) { --*this; }

    /**
     * Set the data value to the given value. This calls the associated storage
     * object set function.
     * @param v The new value.
     */
    template <typename U>
    void operator=(const U &v) { data()->set(v, *params); }

    /**
     * Increment the stat by the given value. This calls the associated
     * storage object inc function.
     * @param v The value to add.
     */
    template <typename U>
    void operator+=(const U &v) { data()->inc(v, *params); }

    /**
     * Decrement the stat by the given value. This calls the associated
     * storage object dec function.
     * @param v The value to substract.
     */
    template <typename U>
    void operator-=(const U &v) { data()->dec(v, *params); }

    /**
     * Return the number of elements, always 1 for a scalar.
     * @return 1.
     */
    size_t size() const { return 1; }

    /**
     * Return true if stat is binned.
     *@return false since Proxies aren't printed/binned
     */
    bool binned() const { return false; }

    /**
     * This stat has no state.  Nothing to reset
     */
    void reset() {  }

  public:
    const StatData *statData() const { return getStatData(stat); }
    std::string str() const
    {
        return csprintf("%s[%d]", this->statData()->name, index);

    }
};

template <class Storage, class Bin>
inline ScalarProxy<Storage, Bin>
VectorBase<Storage, Bin>::operator[](int index)
{
    assert (index >= 0 && index < size());
    return ScalarProxy<Storage, Bin>(bin, params, index, this);
}

template <class Storage, class Bin>
class VectorProxy;

template <class Storage, class Bin>
class Vector2dBase : public DataAccess
{
  public:
    typedef typename Storage::Params params_t;
    typedef typename Bin::template VectorBin<Storage> bin_t;

  protected:
    size_t x;
    size_t y;
    bin_t bin;
    params_t params;

  protected:
    Storage *data(int index) { return bin.data(index, params); }
    const Storage *data(int index) const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(index, *_params);
    }

  public:
    Vector2dBase() {}

    void update(Vector2dData *data)
    {
        int size = this->size();
        data->cvec.resize(size);
        for (int i = 0; i < size; ++i)
            data->cvec[i] = this->data(i)->value(params);
    }

    std::string ysubname(int i) const { return (*this->y_subnames)[i]; }

    friend class VectorProxy<Storage, Bin>;
    VectorProxy<Storage, Bin> operator[](int index);

    size_t size() const { return bin.size(); }
    bool zero() const { return data(0)->value(params) == 0.0; }

    /**
     * Reset stat value to default
     */
    void reset() { bin.reset(); }

    bool check() { return bin.initialized(); }
};

template <class Storage, class Bin>
class VectorProxy
{
  public:
    typedef typename Storage::Params params_t;
    typedef typename Bin::template VectorBin<Storage> bin_t;

  private:
    bin_t *bin;
    params_t *params;
    int offset;
    int len;
    void *stat;

  private:
    mutable VResult *vec;

    Storage *data(int index) {
        assert(index < len);
        return bin->data(offset + index, *params);
    }

    const Storage *data(int index) const {
        bin_t *_bin = const_cast<bin_t *>(bin);
        params_t *_params = const_cast<params_t *>(params);
        return _bin->data(offset + index, *_params);
    }

  public:
    const VResult &result() const {
        if (vec)
            vec->resize(size());
        else
            vec = new VResult(size());

        for (int i = 0; i < size(); ++i)
            (*vec)[i] = data(i)->result(*params);

        return *vec;
    }

    Result total() const {
        Result total = 0.0;
        for (int i = 0; i < size(); ++i)
            total += data(i)->result(*params);
        return total;
    }

  public:
    VectorProxy(bin_t &b, params_t &p, int o, int l, void *s)
        : bin(&b), params(&p), offset(o), len(l), stat(s), vec(NULL)
    {
    }

    VectorProxy(const VectorProxy &sp)
        : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
          stat(sp.stat), vec(NULL)
    {
    }

    ~VectorProxy()
    {
        if (vec)
            delete vec;
    }

    const VectorProxy &operator=(const VectorProxy &sp)
    {
        bin = sp.bin;
        params = sp.params;
        offset = sp.offset;
        len = sp.len;
        stat = sp.stat;
        if (vec)
            delete vec;
        vec = NULL;
        return *this;
    }

    ScalarProxy<Storage, Bin> operator[](int index)
    {
        assert (index >= 0 && index < size());
        return ScalarProxy<Storage, Bin>(*bin, *params, offset + index, stat);
    }

    size_t size() const { return len; }

    /**
     * Return true if stat is binned.
     *@return false since Proxies aren't printed/binned
     */
    bool binned() const { return false; }

    /**
     * This stat has no state.  Nothing to reset.
     */
    void reset() { }
};

template <class Storage, class Bin>
inline VectorProxy<Storage, Bin>
Vector2dBase<Storage, Bin>::operator[](int index)
{
    int offset = index * y;
    assert (index >= 0 && offset < size());
    return VectorProxy<Storage, Bin>(bin, params, offset, y, this);
}

//////////////////////////////////////////////////////////////////////
//
// Non formula statistics
//
//////////////////////////////////////////////////////////////////////

/**
 * Templatized storage and interface for a distrbution stat.
 */
struct DistStor
{
  public:
    /** The parameters for a distribution stat. */
    struct Params
    {
        /** The minimum value to track. */
        Counter min;
        /** The maximum value to track. */
        Counter max;
        /** The number of entries in each bucket. */
        Counter bucket_size;
        /** The number of buckets. Equal to (max-min)/bucket_size. */
        int size;
    };
    enum { fancy = false };

  private:
    /** The smallest value sampled. */
    Counter min_val;
    /** The largest value sampled. */
    Counter max_val;
    /** The number of values sampled less than min. */
    Counter underflow;
    /** The number of values sampled more than max. */
    Counter overflow;
    /** The current sum. */
    Counter sum;
    /** The sum of squares. */
    Counter squares;
    /** The number of samples. */
    Counter samples;
    /** Counter for each bucket. */
    VCounter cvec;

  public:
    /**
     * Construct this storage with the supplied params.
     * @param params The parameters.
     */
    DistStor(const Params &params)
        : min_val(INT_MAX), max_val(INT_MIN), underflow(Counter()),
          overflow(Counter()), sum(Counter()), squares(Counter()),
          samples(Counter()), cvec(params.size)
    {
        reset();
    }

    /**
     * Add a value to the distribution for the given number of times.
     * @param val The value to add.
     * @param number The number of times to add the value.
     * @param params The paramters of the distribution.
     */
    void sample(Counter val, int number, const Params &params)
    {
        if (val < params.min)
            underflow += number;
        else if (val > params.max)
            overflow += number;
        else {
            int index = (int)floor((val - params.min) / params.bucket_size);
            assert(index < size(params));
            cvec[index] += number;
        }

        if (val < min_val)
            min_val = val;

        if (val > max_val)
            max_val = val;

        Counter sample = val * number;
        sum += sample;
        squares += sample * sample;
        samples += number;
    }

    /**
     * Return the number of buckets in this distribution.
     * @return the number of buckets.
     * @todo Is it faster to return the size from the parameters?
     */
    size_t size(const Params &) const { return cvec.size(); }

    /**
     * Returns true if any calls to sample have been made.
     * @param params The paramters of the distribution.
     * @return True if any values have been sampled.
     */
    bool zero(const Params &params) const
    {
        return samples == Counter();
    }

    void update(DistDataData *data, const Params &params)
    {
        data->min = params.min;
        data->max = params.max;
        data->bucket_size = params.bucket_size;
        data->size = params.size;

        data->min_val = (min_val == INT_MAX) ? 0 : min_val;
        data->max_val = (max_val == INT_MIN) ? 0 : max_val;
        data->underflow = underflow;
        data->overflow = overflow;
        data->cvec.resize(params.size);
        for (int i = 0; i < params.size; ++i)
            data->cvec[i] = cvec[i];

        data->sum = sum;
        data->squares = squares;
        data->samples = samples;
    }

    /**
     * Reset stat value to default
     */
    void reset()
    {
        min_val = INT_MAX;
        max_val = INT_MIN;
        underflow = 0;
        overflow = 0;

        int size = cvec.size();
        for (int i = 0; i < size; ++i)
            cvec[i] = Counter();

        sum = Counter();
        squares = Counter();
        samples = Counter();
    }
};

/**
 * Templatized storage and interface for a distribution that calculates mean
 * and variance.
 */
struct FancyStor
{
  public:
    /**
     * No paramters for this storage.
     */
    struct Params {};
    enum { fancy = true };

  private:
    /** The current sum. */
    Counter sum;
    /** The sum of squares. */
    Counter squares;
    /** The number of samples. */
    Counter samples;

  public:
    /**
     * Create and initialize this storage.
     */
    FancyStor(const Params &)
        : sum(Counter()), squares(Counter()), samples(Counter())
    { }

    /**
     * Add a value the given number of times to this running average.
     * Update the running sum and sum of squares, increment the number of
     * values seen by the given number.
     * @param val The value to add.
     * @param number The number of times to add the value.
     * @param p The parameters of this stat.
     */
    void sample(Counter val, int number, const Params &p)
    {
        Counter value = val * number;
        sum += value;
        squares += value * value;
        samples += number;
    }

    void update(DistDataData *data, const Params &params)
    {
        data->sum = sum;
        data->squares = squares;
        data->samples = samples;
    }

    /**
     * Return the number of entries in this stat, 1
     * @return 1.
     */
    size_t size(const Params &) const { return 1; }

    /**
     * Return true if no samples have been added.
     * @return True if no samples have been added.
     */
    bool zero(const Params &) const { return samples == Counter(); }

    /**
     * Reset stat value to default
     */
    void reset()
    {
        sum = Counter();
        squares = Counter();
        samples = Counter();
    }
};

/**
 * Templatized storage for distribution that calculates per cycle mean and
 * variance.
 */
struct AvgFancy
{
  public:
    /** No parameters for this storage. */
    struct Params {};
    enum { fancy = true };

  private:
    /** Current total. */
    Counter sum;
    /** Current sum of squares. */
    Counter squares;

  public:
    /**
     * Create and initialize this storage.
     */
    AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {}

    /**
     * Add a value to the distribution for the given number of times.
     * Update the running sum and sum of squares.
     * @param val The value to add.
     * @param number The number of times to add the value.
     * @param p The paramters of the distribution.
     */
    void sample(Counter val, int number, const Params &p)
    {
        Counter value = val * number;
        sum += value;
        squares += value * value;
    }

    void update(DistDataData *data, const Params &params)
    {
        data->sum = sum;
        data->squares = squares;
        data->samples = curTick;
    }

    /**
     * Return the number of entries, in this case 1.
     * @return 1.
     */
    size_t size(const Params &params) const { return 1; }
    /**
     * Return true if no samples have been added.
     * @return True if the sum is zero.
     */
    bool zero(const Params &params) const { return sum == Counter(); }
    /**
     * Reset stat value to default
     */
    void reset()
    {
        sum = Counter();
        squares = Counter();
    }
};

/**
 * Implementation of a distribution stat. The type of distribution is
 * determined by the Storage template. @sa ScalarBase
 */
template <class Storage, class Bin>
class DistBase : public DataAccess
{
  public:
    /** Define the params of the storage class. */
    typedef typename Storage::Params params_t;
    /** Define the bin type. */
    typedef typename Bin::template Bin<Storage> bin_t;

  protected:
    /** The bin of this stat. */
    bin_t bin;
    /** The parameters for this stat. */
    params_t params;

  protected:
    /**
     * Retrieve the storage from the bin.
     * @return The storage object for this stat.
     */
    Storage *data() { return bin.data(params); }
    /**
     * Retrieve a const pointer to the storage from the bin.
     * @return A const pointer to the storage object for this stat.
     */
    const Storage *data() const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(*_params);
    }

  public:
    DistBase() { }

    /**
     * Add a value to the distribtion n times. Calls sample on the storage
     * class.
     * @param v The value to add.
     * @param n The number of times to add it, defaults to 1.
     */
    template <typename U>
    void sample(const U &v, int n = 1) { data()->sample(v, n, params); }

    /**
     * Return the number of entries in this stat.
     * @return The number of entries.
     */
    size_t size() const { return data()->size(params); }
    /**
     * Return true if no samples have been added.
     * @return True if there haven't been any samples.
     */
    bool zero() const { return data()->zero(params); }

    void update(DistData *base)
    {
        base->data.fancy = Storage::fancy;
        data()->update(&(base->data), params);
    }
    /**
     * @return True is stat is binned.
     */
    bool binned() const { return bin_t::binned; }
    /**
     * Reset stat value to default
     */
    void reset()
    {
        bin.reset();
    }

    bool check() { return bin.initialized(); }
};

template <class Storage, class Bin>
class DistProxy;

template <class Storage, class Bin>
class VectorDistBase : public DataAccess
{
  public:
    typedef typename Storage::Params params_t;
    typedef typename Bin::template VectorBin<Storage> bin_t;

  protected:
    bin_t bin;
    params_t params;

  protected:
    Storage *data(int index) { return bin.data(index, params); }
    const Storage *data(int index) const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(index, *_params);
    }

  public:
    VectorDistBase() {}

    friend class DistProxy<Storage, Bin>;
    DistProxy<Storage, Bin> operator[](int index);
    const DistProxy<Storage, Bin> operator[](int index) const;

    size_t size() const { return bin.size(); }
    bool zero() const { return false; }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    bool binned() const { return bin_t::binned; }
    /**
     * Reset stat value to default
     */
    void reset() { bin.reset(); }

    bool check() { return bin.initialized(); }
    void update(VectorDistData *base)
    {
        int size = this->size();
        base->data.resize(size);
        for (int i = 0; i < size; ++i) {
            base->data[i].fancy = Storage::fancy;
            data(i)->update(&(base->data[i]), params);
        }
    }
};

template <class Storage, class Bin>
class DistProxy
{
  public:
    typedef typename Storage::Params params_t;
    typedef typename Bin::template Bin<Storage> bin_t;
    typedef VectorDistBase<Storage, Bin> base_t;

  private:
    union {
        base_t *stat;
        const base_t *cstat;
    };
    int index;

  protected:
    Storage *data() { return stat->data(index); }
    const Storage *data() const { return cstat->data(index); }

  public:
    DistProxy(const VectorDistBase<Storage, Bin> &s, int i)
        : cstat(&s), index(i) {}
    DistProxy(const DistProxy &sp)
        : cstat(sp.cstat), index(sp.index) {}
    const DistProxy &operator=(const DistProxy &sp) {
        cstat = sp.cstat; index = sp.index; return *this;
    }

  public:
    template <typename U>
    void sample(const U &v, int n = 1) { data()->sample(v, n, cstat->params); }

    size_t size() const { return 1; }
    bool zero() const { return data()->zero(cstat->params); }
    /**
     * Return true if stat is binned.
     *@return false since Proxies are not binned/printed.
     */
    bool binned() const { return false; }
    /**
     * Proxy has no state.  Nothing to reset.
     */
    void reset() { }
};

template <class Storage, class Bin>
inline DistProxy<Storage, Bin>
VectorDistBase<Storage, Bin>::operator[](int index)
{
    assert (index >= 0 && index < size());
    return DistProxy<Storage, Bin>(*this, index);
}

template <class Storage, class Bin>
inline const DistProxy<Storage, Bin>
VectorDistBase<Storage, Bin>::operator[](int index) const
{
    assert (index >= 0 && index < size());
    return DistProxy<Storage, Bin>(*this, index);
}

#if 0
template <class Storage, class Bin>
Result
VectorDistBase<Storage, Bin>::total(int index) const
{
    int total = 0;
    for (int i=0; i < x_size(); ++i) {
        total += data(i)->result(*params);
    }
}
#endif

//////////////////////////////////////////////////////////////////////
//
//  Formula Details
//
//////////////////////////////////////////////////////////////////////

/**
 * Base class for formula statistic node. These nodes are used to build a tree
 * that represents the formula.
 */
class Node : public RefCounted
{
  public:
    /**
     * Return the number of nodes in the subtree starting at this node.
     * @return the number of nodes in this subtree.
     */
    virtual size_t size() const = 0;
    /**
     * Return the result vector of this subtree.
     * @return The result vector of this subtree.
     */
    virtual const VResult &result() const = 0;
    /**
     * Return the total of the result vector.
     * @return The total of the result vector.
     */
    virtual Result total() const = 0;
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    virtual bool binned() const = 0;

    /**
     *
     */
    virtual std::string str() const = 0;
};

/** Reference counting pointer to a function Node. */
typedef RefCountingPtr<Node> NodePtr;

class ScalarStatNode : public Node
{
  private:
    const ScalarData *data;
    mutable VResult vresult;

  public:
    ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {}
    virtual const VResult &result() const
    {
        vresult[0] = data->result();
        return vresult;
    }
    virtual Result total() const { return data->result(); };

    virtual size_t size() const { return 1; }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    virtual bool binned() const { return data->binned(); }

    /**
     *
     */
    virtual std::string str() const { return data->name; }
};

template <class Storage, class Bin>
class ScalarProxyNode : public Node
{
  private:
    const ScalarProxy<Storage, Bin> proxy;
    mutable VResult vresult;

  public:
    ScalarProxyNode(const ScalarProxy<Storage, Bin> &p)
        : proxy(p), vresult(1) { }
    virtual const VResult &result() const
    {
        vresult[0] = proxy.result();
        return vresult;
    }
    virtual Result total() const { return proxy.result(); };

    virtual size_t size() const { return 1; }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    virtual bool binned() const { return proxy.binned(); }

    /**
     *
     */
    virtual std::string str() const { return proxy.str(); }
};

class VectorStatNode : public Node
{
  private:
    const VectorData *data;

  public:
    VectorStatNode(const VectorData *d) : data(d) { }
    virtual const VResult &result() const { return data->result(); }
    virtual Result total() const { return data->total(); };

    virtual size_t size() const { return data->size(); }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    virtual bool binned() const { return data->binned(); }

    virtual std::string str() const { return data->name; }
};

template <class T>
class ConstNode : public Node
{
  private:
    VResult vresult;

  public:
    ConstNode(T s) : vresult(1, (Result)s) {}
    const VResult &result() const { return vresult; }
    virtual Result total() const { return vresult[0]; };
    virtual size_t size() const { return 1; }

    /**
     * Return true if stat is binned.
     *@return False since constants aren't binned.
     */
    virtual bool binned() const { return false; }

    virtual std::string str() const { return to_string(vresult[0]); }
};

template <class Op>
struct OpString;

template<>
struct OpString<std::plus<Result> >
{
    static std::string str() { return "+"; }
};

template<>
struct OpString<std::minus<Result> >
{
    static std::string str() { return "-"; }
};

template<>
struct OpString<std::multiplies<Result> >
{
    static std::string str() { return "*"; }
};

template<>
struct OpString<std::divides<Result> >
{
    static std::string str() { return "/"; }
};

template<>
struct OpString<std::modulus<Result> >
{
    static std::string str() { return "%"; }
};

template<>
struct OpString<std::negate<Result> >
{
    static std::string str() { return "-"; }
};

template <class Op>
class UnaryNode : public Node
{
  public:
    NodePtr l;
    mutable VResult vresult;

  public:
    UnaryNode(NodePtr &p) : l(p) {}

    const VResult &result() const
    {
        const VResult &lvec = l->result();
        int size = lvec.size();

        assert(size > 0);

        vresult.resize(size);
        Op op;
        for (int i = 0; i < size; ++i)
            vresult[i] = op(lvec[i]);

        return vresult;
    }

    Result total() const {
        Op op;
        return op(l->total());
    }

    virtual size_t size() const { return l->size(); }
    /**
     * Return true if child of node is binned.
     *@return True if child of node is binned.
     */
    virtual bool binned() const { return l->binned(); }

    virtual std::string str() const
    {
        return OpString<Op>::str() + l->str();
    }
};

template <class Op>
class BinaryNode : public Node
{
  public:
    NodePtr l;
    NodePtr r;
    mutable VResult vresult;

  public:
    BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}

    const VResult &result() const
    {
        Op op;
        const VResult &lvec = l->result();
        const VResult &rvec = r->result();

        assert(lvec.size() > 0 && rvec.size() > 0);

        if (lvec.size() == 1 && rvec.size() == 1) {
            vresult.resize(1);
            vresult[0] = op(lvec[0], rvec[0]);
        } else if (lvec.size() == 1) {
            int size = rvec.size();
            vresult.resize(size);
            for (int i = 0; i < size; ++i)
                vresult[i] = op(lvec[0], rvec[i]);
        } else if (rvec.size() == 1) {
            int size = lvec.size();
            vresult.resize(size);
            for (int i = 0; i < size; ++i)
                vresult[i] = op(lvec[i], rvec[0]);
        } else if (rvec.size() == lvec.size()) {
            int size = rvec.size();
            vresult.resize(size);
            for (int i = 0; i < size; ++i)
                vresult[i] = op(lvec[i], rvec[i]);
        }

        return vresult;
    }

    Result total() const {
        Op op;
        return op(l->total(), r->total());
    }

    virtual size_t size() const {
        int ls = l->size();
        int rs = r->size();
        if (ls == 1)
            return rs;
        else if (rs == 1)
            return ls;
        else {
            assert(ls == rs && "Node vector sizes are not equal");
            return ls;
        }
    }
    /**
     * Return true if any children of node are binned
     *@return True if either child of node is binned.
     */
    virtual bool binned() const { return (l->binned() || r->binned()); }

    virtual std::string str() const
    {
        return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
    }
};

template <class Op>
class SumNode : public Node
{
  public:
    NodePtr l;
    mutable VResult vresult;

  public:
    SumNode(NodePtr &p) : l(p), vresult(1) {}

    const VResult &result() const
    {
        const VResult &lvec = l->result();
        int size = lvec.size();
        assert(size > 0);

        vresult[0] = 0.0;

        Op op;
        for (int i = 0; i < size; ++i)
            vresult[0] = op(vresult[0], lvec[i]);

        return vresult;
    }

    Result total() const
    {
        const VResult &lvec = l->result();
        int size = lvec.size();
        assert(size > 0);

        Result vresult = 0.0;

        Op op;
        for (int i = 0; i < size; ++i)
            vresult = op(vresult, lvec[i]);

        return vresult;
    }

    virtual size_t size() const { return 1; }
    /**
     * Return true if child of node is binned.
     *@return True if child of node is binned.
     */
    virtual bool binned() const { return l->binned(); }

    virtual std::string str() const
    {
        return csprintf("total(%s)", l->str());
    }
};


//////////////////////////////////////////////////////////////////////
//
// Visible Statistics Types
//
//////////////////////////////////////////////////////////////////////
/**
 * @defgroup VisibleStats "Statistic Types"
 * These are the statistics that are used in the simulator. By default these
 * store counters and don't use binning, but are templatized to accept any type
 * and any Bin class.
 * @{
 */

/**
 * This is an easy way to assign all your stats to be binned or not
 * binned.  If the typedef is NoBin, nothing is binned.  If it is
 * MainBin, then all stats are binned under that Bin.
 */
#if STATS_BINNING
typedef MainBin DefaultBin;
#else
typedef NoBin DefaultBin;
#endif

/**
 * This is a simple scalar statistic, like a counter.
 * @sa Stat, ScalarBase, StatStor
 */
template <class Bin = DefaultBin>
class Scalar
    : public Wrap<Scalar<Bin>,
                  ScalarBase<StatStor, Bin>,
                  ScalarStatData>
{
  public:
    /** The base implementation. */
    typedef ScalarBase<StatStor, Bin> Base;

    Scalar()
    {
        this->setInit();
    }

    /**
     * Sets the stat equal to the given value. Calls the base implementation
     * of operator=
     * @param v The new value.
     */
    template <typename U>
    void operator=(const U &v) { Base::operator=(v); }
};

class Value
    : public Wrap<Value,
                  ValueBase,
                  ScalarStatData>
{
  public:
    /** The base implementation. */
    typedef ValueBase Base;

    template <class T>
    Value &scalar(T &value)
    {
        Base::scalar(value);
        return *this;
    }

    template <class T>
    Value &functor(T &func)
    {
        Base::functor(func);
        return *this;
    }
};

/**
 * A stat that calculates the per cycle average of a value.
 * @sa Stat, ScalarBase, AvgStor
 */
template <class Bin = DefaultBin>
class Average
    : public Wrap<Average<Bin>,
                  ScalarBase<AvgStor, Bin>,
                  ScalarStatData>
{
  public:
    /** The base implementation. */
    typedef ScalarBase<AvgStor, Bin> Base;

    Average()
    {
        this->setInit();
    }

    /**
     * Sets the stat equal to the given value. Calls the base implementation
     * of operator=
     * @param v The new value.
     */
    template <typename U>
    void operator=(const U &v) { Base::operator=(v); }
};

/**
 * A vector of scalar stats.
 * @sa Stat, VectorBase, StatStor
 */
template <class Bin = DefaultBin>
class Vector
    : public WrapVec<Vector<Bin>,
                     VectorBase<StatStor, Bin>,
                     VectorStatData>
{
  public:
    /** The base implementation. */
    typedef ScalarBase<StatStor, Bin> Base;

    /**
     * Set this vector to have the given size.
     * @param size The new size.
     * @return A reference to this stat.
     */
    Vector &init(size_t size) {
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * A vector of Average stats.
 * @sa Stat, VectorBase, AvgStor
 */
template <class Bin = DefaultBin>
class AverageVector
    : public WrapVec<AverageVector<Bin>,
                     VectorBase<AvgStor, Bin>,
                     VectorStatData>
{
  public:
    /**
     * Set this vector to have the given size.
     * @param size The new size.
     * @return A reference to this stat.
     */
    AverageVector &init(size_t size) {
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * A 2-Dimensional vecto of scalar stats.
 * @sa Stat, Vector2dBase, StatStor
 */
template <class Bin = DefaultBin>
class Vector2d
    : public WrapVec2d<Vector2d<Bin>,
                       Vector2dBase<StatStor, Bin>,
                       Vector2dStatData>
{
  public:
    Vector2d &init(size_t _x, size_t _y) {
        this->statData()->x = this->x = _x;
        this->statData()->y = this->y = _y;
        this->bin.init(this->x * this->y, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * A simple distribution stat.
 * @sa Stat, DistBase, DistStor
 */
template <class Bin = DefaultBin>
class Distribution
    : public Wrap<Distribution<Bin>,
                  DistBase<DistStor, Bin>,
                  DistStatData>
{
  public:
    /** Base implementation. */
    typedef DistBase<DistStor, Bin> Base;
    /** The Parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Set the parameters of this distribution. @sa DistStor::Params
     * @param min The minimum value of the distribution.
     * @param max The maximum value of the distribution.
     * @param bkt The number of values in each bucket.
     * @return A reference to this distribution.
     */
    Distribution &init(Counter min, Counter max, Counter bkt) {
        this->params.min = min;
        this->params.max = max;
        this->params.bucket_size = bkt;
        this->params.size = (int)rint((max - min) / bkt + 1.0);
        this->bin.init(this->params);
        this->setInit();

        return *this;
    }
};

/**
 * Calculates the mean and variance of all the samples.
 * @sa Stat, DistBase, FancyStor
 */
template <class Bin = DefaultBin>
class StandardDeviation
    : public Wrap<StandardDeviation<Bin>,
                  DistBase<FancyStor, Bin>,
                  DistStatData>
{
  public:
    /** The base implementation */
    typedef DistBase<DistStor, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Construct and initialize this distribution.
     */
    StandardDeviation() {
        this->bin.init(this->params);
        this->setInit();
    }
};

/**
 * Calculates the per cycle mean and variance of the samples.
 * @sa Stat, DistBase, AvgFancy
 */
template <class Bin = DefaultBin>
class AverageDeviation
    : public Wrap<AverageDeviation<Bin>,
                  DistBase<AvgFancy, Bin>,
                  DistStatData>
{
  public:
    /** The base implementation */
    typedef DistBase<DistStor, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Construct and initialize this distribution.
     */
    AverageDeviation()
    {
        this->bin.init(this->params);
        this->setInit();
    }
};

/**
 * A vector of distributions.
 * @sa Stat, VectorDistBase, DistStor
 */
template <class Bin = DefaultBin>
class VectorDistribution
    : public WrapVec<VectorDistribution<Bin>,
                     VectorDistBase<DistStor, Bin>,
                     VectorDistStatData>
{
  public:
    /** The base implementation */
    typedef VectorDistBase<DistStor, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Initialize storage and parameters for this distribution.
     * @param size The size of the vector (the number of distributions).
     * @param min The minimum value of the distribution.
     * @param max The maximum value of the distribution.
     * @param bkt The number of values in each bucket.
     * @return A reference to this distribution.
     */
    VectorDistribution &init(int size, Counter min, Counter max, Counter bkt) {
        this->params.min = min;
        this->params.max = max;
        this->params.bucket_size = bkt;
        this->params.size = (int)rint((max - min) / bkt + 1.0);
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * This is a vector of StandardDeviation stats.
 * @sa Stat, VectorDistBase, FancyStor
 */
template <class Bin = DefaultBin>
class VectorStandardDeviation
    : public WrapVec<VectorStandardDeviation<Bin>,
                     VectorDistBase<FancyStor, Bin>,
                     VectorDistStatData>
{
  public:
    /** The base implementation */
    typedef VectorDistBase<FancyStor, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Initialize storage for this distribution.
     * @param size The size of the vector.
     * @return A reference to this distribution.
     */
    VectorStandardDeviation &init(int size) {
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * This is a vector of AverageDeviation stats.
 * @sa Stat, VectorDistBase, AvgFancy
 */
template <class Bin = DefaultBin>
class VectorAverageDeviation
    : public WrapVec<VectorAverageDeviation<Bin>,
                     VectorDistBase<AvgFancy, Bin>,
                     VectorDistStatData>
{
  public:
    /** The base implementation */
    typedef VectorDistBase<AvgFancy, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Initialize storage for this distribution.
     * @param size The size of the vector.
     * @return A reference to this distribution.
     */
    VectorAverageDeviation &init(int size) {
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * A formula for statistics that is calculated when printed. A formula is
 * stored as a tree of Nodes that represent the equation to calculate.
 * @sa Stat, ScalarStat, VectorStat, Node, Temp
 */
class FormulaBase : public DataAccess
{
  protected:
    /** The root of the tree which represents the Formula */
    NodePtr root;
    friend class Temp;

  public:
    /**
     * Return the result of the Fomula in a vector.  If there were no Vector
     * components to the Formula, then the vector is size 1.  If there were,
     * like x/y with x being a vector of size 3, then the result returned will
     * be x[0]/y, x[1]/y, x[2]/y, respectively.
     * @return The result vector.
     */
    void result(VResult &vec) const;

    /**
     * Return the total Formula result.  If there is a Vector
     * component to this Formula, then this is the result of the
     * Formula if the formula is applied after summing all the
     * components of the Vector.  For example, if Formula is x/y where
     * x is size 3, then total() will return (x[1]+x[2]+x[3])/y.  If
     * there is no Vector component, total() returns the same value as
     * the first entry in the VResult val() returns.
     * @return The total of the result vector.
     */
    Result total() const;

    /**
     * Return the number of elements in the tree.
     */
    size_t size() const;

    /**
     * Return true if Formula is binned. i.e. any of its children
     * nodes are binned
     * @return True if Formula is binned.
     */
    bool binned() const;

    bool check() const { return true; }

    /**
     * Formulas don't need to be reset
     */
    void reset();

    /**
     *
     */
    bool zero() const;

    /**
     *
     */
    void update(StatData *);

    std::string str() const;
};

class FormulaData : public VectorData
{
  public:
    virtual std::string str() const = 0;
    virtual bool check() const { return true; }
};

template <class Stat>
class FormulaStatData : public FormulaData
{
  protected:
    Stat &s;
    mutable VResult vec;
    mutable VCounter cvec;

  public:
    FormulaStatData(Stat &stat) : s(stat) {}

    virtual bool binned() const { return s.binned(); }
    virtual bool zero() const { return s.zero(); }
    virtual void reset() { s.reset(); }

    virtual size_t size() const { return s.size(); }
    virtual const VResult &result() const
    {
        s.result(vec);
        return vec;
    }
    virtual Result total() const { return s.total(); }
    virtual VCounter &value() const { return cvec; }
    virtual void visit(Visit &visitor)
    {
        update();
        s.update(this);
        visitor.visit(*this);
    }
    virtual std::string str() const { return s.str(); }
};

class Temp;
class Formula
    : public WrapVec<Formula,
                     FormulaBase,
                     FormulaStatData>
{
  public:
    /**
     * Create and initialize thie formula, and register it with the database.
     */
    Formula();

    /**
     * Create a formula with the given root node, register it with the
     * database.
     * @param r The root of the expression tree.
     */
    Formula(Temp r);

    /**
     * Set an unitialized Formula to the given root.
     * @param r The root of the expression tree.
     * @return a reference to this formula.
     */
    const Formula &operator=(Temp r);

    /**
     * Add the given tree to the existing one.
     * @param r The root of the expression tree.
     * @return a reference to this formula.
     */
    const Formula &operator+=(Temp r);
};

class FormulaNode : public Node
{
  private:
    const Formula &formula;
    mutable VResult vec;

  public:
    FormulaNode(const Formula &f) : formula(f) {}

    virtual size_t size() const { return formula.size(); }
    virtual const VResult &result() const { formula.result(vec); return vec; }
    virtual Result total() const { return formula.total(); }
    virtual bool binned() const { return formula.binned(); }

    virtual std::string str() const { return formula.str(); }
};

/**
 * Helper class to construct formula node trees.
 */
class Temp
{
  protected:
    /**
     * Pointer to a Node object.
     */
    NodePtr node;

  public:
    /**
     * Copy the given pointer to this class.
     * @param n A pointer to a Node object to copy.
     */
    Temp(NodePtr n) : node(n) { }

    /**
     * Return the node pointer.
     * @return the node pointer.
     */
    operator NodePtr&() { return node;}

  public:
    /**
     * Create a new ScalarStatNode.
     * @param s The ScalarStat to place in a node.
     */
    template <class Bin>
    Temp(const Scalar<Bin> &s)
        : node(new ScalarStatNode(s.statData())) { }

    /**
     * Create a new ScalarStatNode.
     * @param s The ScalarStat to place in a node.
     */
    Temp(const Value &s)
        : node(new ScalarStatNode(s.statData())) { }

    /**
     * Create a new ScalarStatNode.
     * @param s The ScalarStat to place in a node.
     */
    template <class Bin>
    Temp(const Average<Bin> &s)
        : node(new ScalarStatNode(s.statData())) { }

    /**
     * Create a new VectorStatNode.
     * @param s The VectorStat to place in a node.
     */
    template <class Bin>
    Temp(const Vector<Bin> &s)
        : node(new VectorStatNode(s.statData())) { }

    /**
     *
     */
    Temp(const Formula &f)
        : node(new FormulaNode(f)) { }

    /**
     * Create a new ScalarProxyNode.
     * @param p The ScalarProxy to place in a node.
     */
    template <class Storage, class Bin>
    Temp(const ScalarProxy<Storage, Bin> &p)
        : node(new ScalarProxyNode<Storage, Bin>(p)) { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed char value)
        : node(new ConstNode<signed char>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned char value)
        : node(new ConstNode<unsigned char>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed short value)
        : node(new ConstNode<signed short>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned short value)
        : node(new ConstNode<unsigned short>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed int value)
        : node(new ConstNode<signed int>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned int value)
        : node(new ConstNode<unsigned int>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed long value)
        : node(new ConstNode<signed long>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned long value)
        : node(new ConstNode<unsigned long>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed long long value)
        : node(new ConstNode<signed long long>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned long long value)
        : node(new ConstNode<unsigned long long>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(float value)
        : node(new ConstNode<float>(value)) {}

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(double value)
        : node(new ConstNode<double>(value)) {}
};


/**
 * @}
 */

void check();
void reset();
void registerResetCallback(Callback *cb);

inline Temp
operator+(Temp l, Temp r)
{
    return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
}

inline Temp
operator-(Temp l, Temp r)
{
    return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
}

inline Temp
operator*(Temp l, Temp r)
{
    return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
}

inline Temp
operator/(Temp l, Temp r)
{
    return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
}

inline Temp
operator-(Temp l)
{
    return NodePtr(new UnaryNode<std::negate<Result> >(l));
}

template <typename T>
inline Temp
constant(T val)
{
    return NodePtr(new ConstNode<T>(val));
}

inline Temp
sum(Temp val)
{
    return NodePtr(new SumNode<std::plus<Result> >(val));
}

/* namespace Stats */ }

#endif // __BASE_STATISTICS_HH__
