...

Commits (6)
src/Cartesian.h 0 → 100644
 #ifndef CARTESIAN_H_ #define CARTESIAN_H_ #include #include /** * A small class to iterate over the Cartesian products of a few sequences with number ranges, such * as 0, 1, 2 and 0, 1 and 0, 1, 2, 3. All the sequences start from 0. */ template class Cartesian { private: std::vector upperBounds; // The largest integers we should never touch. public: inline const decltype(upperBounds)& getUpperBounds() const noexcept { return upperBounds; } // The iterator class Iterator { private: std::vector cur; // Current iterated product. bool overflown; const Cartesian * c; public: Iterator() noexcept : overflown(false) , c(nullptr) {} Iterator(const Cartesian& c, bool of = false) noexcept : overflown(of) { this->c = &c; cur.assign(c.getUpperBounds().size(), 0); } inline bool isOverflown() const noexcept { return overflown; } inline const Cartesian * getCartesian() const noexcept { return c; } inline Iterator& operator ++ () noexcept { typename decltype(cur)::size_type i = 0; while (true) { ++ cur[i]; if (cur[i] < getCartesian()->getUpperBounds().at(i)) break; cur[i] = 0; ++ i; // We've done with the last one. We now overflow. if (i >= cur.size()) { overflown = true; break; } } return *this; } inline Iterator operator ++ (int) noexcept { Iterator it(*this); operator ++ (); return it; } inline const decltype(cur)& operator * () const noexcept { return cur; } inline const decltype(cur)* operator -> () const noexcept { return &cur; } inline bool operator == (const Iterator& other) const noexcept { return **this == *other && isOverflown() == other.isOverflown() && getCartesian() == other.getCartesian(); } inline bool operator != (const Iterator& other) const noexcept { return !(*this == other); } }; const Iterator begin() const noexcept { return Iterator(*this); } const Iterator end() const noexcept { return Iterator(*this, true); } template Cartesian(Iter beg, Iter end) noexcept // Beg and end contains the max integer of each sequence plus 1. { std::copy(beg, end, std::back_inserter(upperBounds)); } }; #endif // CARTESIAN_H_