2013-02-07 17:50:02 +00:00
|
|
|
#ifndef YAP_PACKAGES_CLPBN_HORUS_INDEXER_H_
|
|
|
|
#define YAP_PACKAGES_CLPBN_HORUS_INDEXER_H_
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-07 20:09:10 +00:00
|
|
|
#include <vector>
|
2012-05-23 14:56:01 +01:00
|
|
|
#include <algorithm>
|
2012-05-28 17:57:45 +01:00
|
|
|
#include <numeric>
|
2012-05-23 14:56:01 +01:00
|
|
|
|
|
|
|
#include "Util.h"
|
|
|
|
|
|
|
|
|
2013-02-08 21:12:46 +00:00
|
|
|
namespace Horus {
|
2013-02-07 23:53:13 +00:00
|
|
|
|
2013-02-13 14:26:47 +00:00
|
|
|
class Indexer {
|
2012-05-23 14:56:01 +01:00
|
|
|
public:
|
2013-02-06 00:24:02 +00:00
|
|
|
Indexer (const Ranges& ranges, bool calcOffsets = true);
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
void increment();
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
void incrementDimension (size_t dim);
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
void incrementExceptDimension (size_t dim);
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
Indexer& operator++();
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
operator size_t() const;
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
unsigned operator[] (size_t dim) const;
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
bool valid() const;
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
void reset();
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
void resetDimension (size_t dim);
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
size_t size() const;
|
2012-05-23 14:56:01 +01:00
|
|
|
|
|
|
|
private:
|
2013-02-28 19:45:37 +00:00
|
|
|
void calculateOffsets();
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-07 22:37:45 +00:00
|
|
|
friend std::ostream& operator<< (std::ostream&, const Indexer&);
|
|
|
|
|
2013-02-07 13:37:15 +00:00
|
|
|
size_t index_;
|
|
|
|
Ranges indices_;
|
|
|
|
const Ranges& ranges_;
|
|
|
|
size_t size_;
|
|
|
|
std::vector<size_t> offsets_;
|
2012-12-27 22:25:45 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN (Indexer);
|
2012-05-23 14:56:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
inline
|
|
|
|
Indexer::Indexer (const Ranges& ranges, bool calcOffsets)
|
|
|
|
: index_(0), indices_(ranges.size(), 0), ranges_(ranges),
|
2013-02-08 21:01:53 +00:00
|
|
|
size_(Util::sizeExpected (ranges))
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
if (calcOffsets) {
|
|
|
|
calculateOffsets();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void
|
2013-02-28 19:45:37 +00:00
|
|
|
Indexer::increment()
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
for (size_t i = ranges_.size(); i-- > 0; ) {
|
|
|
|
indices_[i] ++;
|
|
|
|
if (indices_[i] != ranges_[i]) {
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
indices_[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
index_ ++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void
|
|
|
|
Indexer::incrementDimension (size_t dim)
|
|
|
|
{
|
|
|
|
assert (dim < ranges_.size());
|
|
|
|
assert (ranges_.size() == offsets_.size());
|
|
|
|
assert (indices_[dim] < ranges_[dim]);
|
|
|
|
indices_[dim] ++;
|
|
|
|
index_ += offsets_[dim];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void
|
|
|
|
Indexer::incrementExceptDimension (size_t dim)
|
|
|
|
{
|
|
|
|
assert (ranges_.size() == offsets_.size());
|
|
|
|
for (size_t i = ranges_.size(); i-- > 0; ) {
|
|
|
|
if (i != dim) {
|
|
|
|
indices_[i] ++;
|
|
|
|
index_ += offsets_[i];
|
|
|
|
if (indices_[i] != ranges_[i]) {
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
indices_[i] = 0;
|
|
|
|
index_ -= offsets_[i] * ranges_[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
index_ = size_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline Indexer&
|
2013-02-28 19:45:37 +00:00
|
|
|
Indexer::operator++()
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
increment();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline
|
2013-02-28 19:45:37 +00:00
|
|
|
Indexer::operator size_t() const
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
return index_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
Indexer::operator[] (size_t dim) const
|
|
|
|
{
|
|
|
|
assert (valid());
|
|
|
|
assert (dim < ranges_.size());
|
|
|
|
return indices_[dim];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline bool
|
2013-02-28 19:45:37 +00:00
|
|
|
Indexer::valid() const
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
return index_ < size_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void
|
2013-02-28 19:45:37 +00:00
|
|
|
Indexer::reset()
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
index_ = 0;
|
2013-02-13 15:25:55 +00:00
|
|
|
std::fill (indices_.begin(), indices_.end(), 0);
|
2013-02-06 00:24:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void
|
|
|
|
Indexer::resetDimension (size_t dim)
|
|
|
|
{
|
|
|
|
indices_[dim] = 0;
|
|
|
|
index_ -= offsets_[dim] * ranges_[dim];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline size_t
|
2013-02-28 19:45:37 +00:00
|
|
|
Indexer::size() const
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
return size_ ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void
|
2013-02-28 19:45:37 +00:00
|
|
|
Indexer::calculateOffsets()
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
size_t prod = 1;
|
|
|
|
offsets_.resize (ranges_.size());
|
|
|
|
for (size_t i = ranges_.size(); i-- > 0; ) {
|
|
|
|
offsets_[i] = prod;
|
|
|
|
prod *= ranges_[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-02-13 14:26:47 +00:00
|
|
|
class MapIndexer {
|
2012-05-23 14:56:01 +01:00
|
|
|
public:
|
2013-02-07 13:37:15 +00:00
|
|
|
MapIndexer (const Ranges& ranges, const std::vector<bool>& mask);
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
MapIndexer (const Ranges& ranges, size_t dim);
|
2012-12-20 23:19:10 +00:00
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
template <typename T>
|
|
|
|
MapIndexer (
|
2013-02-07 13:37:15 +00:00
|
|
|
const std::vector<T>& allArgs,
|
2013-02-13 15:25:55 +00:00
|
|
|
const Ranges& allRanges,
|
2013-02-07 13:37:15 +00:00
|
|
|
const std::vector<T>& wantedArgs,
|
2013-02-13 15:25:55 +00:00
|
|
|
const Ranges& wantedRanges);
|
2012-05-26 20:56:41 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
MapIndexer& operator++();
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
operator size_t() const;
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
unsigned operator[] (size_t dim) const;
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
bool valid() const;
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
void reset();
|
2012-05-23 14:56:01 +01:00
|
|
|
|
|
|
|
private:
|
2013-02-07 22:37:45 +00:00
|
|
|
friend std::ostream& operator<< (std::ostream&, const MapIndexer&);
|
|
|
|
|
2013-02-07 13:37:15 +00:00
|
|
|
size_t index_;
|
|
|
|
Ranges indices_;
|
|
|
|
const Ranges& ranges_;
|
|
|
|
bool valid_;
|
|
|
|
std::vector<size_t> offsets_;
|
2012-12-27 22:25:45 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN (MapIndexer);
|
2012-05-23 14:56:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-05-25 20:15:05 +01:00
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
inline
|
2013-02-16 16:42:08 +00:00
|
|
|
MapIndexer::MapIndexer (
|
|
|
|
const Ranges& ranges,
|
|
|
|
const std::vector<bool>& mask)
|
2013-02-06 00:24:02 +00:00
|
|
|
: index_(0), indices_(ranges.size(), 0), ranges_(ranges),
|
|
|
|
valid_(true)
|
|
|
|
{
|
|
|
|
size_t prod = 1;
|
|
|
|
offsets_.resize (ranges.size(), 0);
|
|
|
|
for (size_t i = ranges.size(); i-- > 0; ) {
|
|
|
|
if (mask[i]) {
|
|
|
|
offsets_[i] = prod;
|
|
|
|
prod *= ranges[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert (ranges.size() == mask.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline
|
|
|
|
MapIndexer::MapIndexer (const Ranges& ranges, size_t dim)
|
|
|
|
: index_(0), indices_(ranges.size(), 0), ranges_(ranges),
|
|
|
|
valid_(true)
|
|
|
|
{
|
|
|
|
size_t prod = 1;
|
|
|
|
offsets_.resize (ranges.size(), 0);
|
|
|
|
for (size_t i = ranges.size(); i-- > 0; ) {
|
|
|
|
if (i != dim) {
|
|
|
|
offsets_[i] = prod;
|
|
|
|
prod *= ranges[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T> inline
|
|
|
|
MapIndexer::MapIndexer (
|
2013-02-07 13:37:15 +00:00
|
|
|
const std::vector<T>& allArgs,
|
2013-02-13 15:25:55 +00:00
|
|
|
const Ranges& allRanges,
|
2013-02-07 13:37:15 +00:00
|
|
|
const std::vector<T>& wantedArgs,
|
2013-02-13 15:25:55 +00:00
|
|
|
const Ranges& wantedRanges)
|
|
|
|
: index_(0), indices_(allArgs.size(), 0), ranges_(allRanges),
|
|
|
|
valid_(true)
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
size_t prod = 1;
|
2013-02-07 13:37:15 +00:00
|
|
|
std::vector<size_t> offsets (wantedRanges.size());
|
2013-02-06 00:24:02 +00:00
|
|
|
for (size_t i = wantedRanges.size(); i-- > 0; ) {
|
|
|
|
offsets[i] = prod;
|
|
|
|
prod *= wantedRanges[i];
|
|
|
|
}
|
|
|
|
offsets_.reserve (allArgs.size());
|
|
|
|
for (size_t i = 0; i < allArgs.size(); i++) {
|
2013-02-08 21:01:53 +00:00
|
|
|
size_t idx = Util::indexOf (wantedArgs, allArgs[i]);
|
2013-02-06 00:24:02 +00:00
|
|
|
offsets_.push_back (idx != wantedArgs.size() ? offsets[idx] : 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline MapIndexer&
|
2013-02-28 19:45:37 +00:00
|
|
|
MapIndexer::operator++()
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
assert (valid_);
|
|
|
|
for (size_t i = ranges_.size(); i-- > 0; ) {
|
|
|
|
indices_[i] ++;
|
|
|
|
index_ += offsets_[i];
|
|
|
|
if (indices_[i] != ranges_[i]) {
|
|
|
|
return *this;
|
|
|
|
} else {
|
|
|
|
indices_[i] = 0;
|
|
|
|
index_ -= offsets_[i] * ranges_[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
valid_ = false;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline
|
2013-02-28 19:45:37 +00:00
|
|
|
MapIndexer::operator size_t() const
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
assert (valid());
|
|
|
|
return index_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
MapIndexer::operator[] (size_t dim) const
|
|
|
|
{
|
|
|
|
assert (valid());
|
|
|
|
assert (dim < ranges_.size());
|
|
|
|
return indices_[dim];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline bool
|
2013-02-28 19:45:37 +00:00
|
|
|
MapIndexer::valid() const
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
return valid_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void
|
2013-02-28 19:45:37 +00:00
|
|
|
MapIndexer::reset()
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
index_ = 0;
|
2013-02-13 15:25:55 +00:00
|
|
|
std::fill (indices_.begin(), indices_.end(), 0);
|
2013-02-06 00:24:02 +00:00
|
|
|
}
|
|
|
|
|
2013-02-08 21:12:46 +00:00
|
|
|
} // namespace Horus
|
2013-02-07 23:53:13 +00:00
|
|
|
|
2013-02-08 00:20:01 +00:00
|
|
|
#endif // YAP_PACKAGES_CLPBN_HORUS_INDEXER_H_
|
2012-05-23 14:56:01 +01:00
|
|
|
|