/*
Texel - A UCI chess engine.
Copyright (C) 2013 Peter Ă–sterlund, peterosterlund2@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* histogram.hpp
*
* Created on: Oct 20, 2013
* Author: petero
*/
#ifndef HISTOGRAM_HPP_
#define HISTOGRAM_HPP_
#include "util.hpp"
/** A histogram over integer range [minV,maxV[. Out of range values are ignored. */
template <int minV, int maxV>
class Histogram {
public:
/** Create an empty histogram. */
Histogram();
/** Set all counts to 0. */
void clear();
/** Add a data point. */
void add(int value, int count = 1);
/** Get count corresponding to value. */
int get(int value) const;
constexpr static int minValue() { return minV; }
constexpr static int maxValue() { return maxV; }
private:
int counts[maxV - minV];
};
/** RAII class that adds a value to a histogram in the destructor.
* The value added is equal to the number of times inc() was called. */
template <typename Histogram>
class HistogramAdder {
public:
/** Constructor. */
HistogramAdder(Histogram& h);
/** Destructor. Adds current value to histogram. */
~HistogramAdder();
/** Increment value to be added to histogram. */
void inc();
private:
int value;
Histogram& hist;
};
template <int minV, int maxV>
inline
Histogram<minV,maxV>::Histogram() {
static_assert(maxV >= minV, "Negative size not allowed");
clear();
}
template <int minV, int maxV>
inline void
Histogram<minV,maxV>::clear() {
for (int i = 0; i < (int)COUNT_OF(counts); i++)
counts[i] = 0;
}
template <int minV, int maxV>
inline void
Histogram<minV,maxV>::add(int value, int count) {
if ((value >= minV) && (value < maxV))
counts[value - minV] += count;
}
template <int minV, int maxV>
inline int
Histogram<minV,maxV>::get(int value) const {
if ((value >= minV) && (value < maxV))
return counts[value - minV];
else
return 0;
}
template <typename Histogram>
inline
HistogramAdder<Histogram>::HistogramAdder(Histogram& h)
: value(0), hist(h) {
}
template <typename Histogram>
inline
HistogramAdder<Histogram>::~HistogramAdder() {
hist.add(value);
}
template <typename Histogram>
inline void
HistogramAdder<Histogram>::inc() {
value++;
}
#endif /* HISTOGRAM_HPP_ */