Skip to content

Instantly share code, notes, and snippets.

@hacst
Created May 25, 2013 19:44
Show Gist options
  • Save hacst/5650513 to your computer and use it in GitHub Desktop.
Save hacst/5650513 to your computer and use it in GitHub Desktop.
Experimentation with typesafe indices for https://plus.google.com/u/0/103771295878903986513/posts/CiwQXgwHbJ1 Basically the gist of what I wanted from a strongly typedef'd size_t. This example only implements the operators I needed and already took quite a bit of code that might (will ;) ) contain bugs and unexpected behavior. For my application…
#include <vector>
#include <cstddef>
template<typename Tag>
class TypesafeIndex
{
public:
inline TypesafeIndex() : m_i() {};
inline explicit TypesafeIndex(const size_t a_value) : m_i(a_value) {};
inline TypesafeIndex<Tag>& operator=(TypesafeIndex<Tag> a_rhs) { m_i = a_rhs.m_i; return *this; };
inline TypesafeIndex<Tag>& operator=(size_t a_rhs) { m_i = a_rhs; return *this; };
inline bool operator==(const Tag a_rhs) const { return m_i == a_rhs; };
inline bool operator==(const TypesafeIndex<Tag> a_rhs) const { return m_i == a_rhs; };
inline bool operator<(const TypesafeIndex<Tag> a_rhs) const { return m_i < a_rhs.m_i; };
inline bool operator<(const size_t a_rhs) const { return m_i < a_rhs; };
inline bool operator<=(const TypesafeIndex<Tag> a_rhs) const { return m_i <= a_rhs.m_i; };
inline bool operator<=(const size_t a_rhs) const { return m_i <= a_rhs; };
inline TypesafeIndex<Tag>& operator++(int) { ++m_i; return *this; };
inline TypesafeIndex<Tag> operator++() { TypesafeIndex<Tag> retval(m_i++); return retval; };
inline TypesafeIndex<Tag>& operator--(int) { --m_i; return *this; };
inline TypesafeIndex<Tag> operator--() { TypesafeIndex<Tag> retval(m_i--); return retval; };
inline TypesafeIndex<Tag> operator-(const TypesafeIndex<Tag> a_rhs) const { return TypesafeIndex<Tag>(m_i - a_rhs.m_i); };
inline TypesafeIndex<Tag> operator-(const size_t a_rhs) const { return TypesafeIndex<Tag>(m_i - a_rhs); };
inline TypesafeIndex<Tag> operator-(const int a_rhs) const { return TypesafeIndex<Tag>(m_i - a_rhs); };
inline TypesafeIndex<Tag> operator+(const TypesafeIndex<Tag> a_rhs) const { return TypesafeIndex<Tag>(m_i + a_rhs.m_i); };
inline TypesafeIndex<Tag> operator+(const size_t a_rhs) const { return TypesafeIndex<Tag>(m_i + a_rhs); };
inline TypesafeIndex<Tag> operator+(const int a_rhs) const { return TypesafeIndex<Tag>(m_i + a_rhs); };
inline operator size_t () const { return m_i; };
private:
size_t m_i;
};
class Matrix {
class IndexXTypeTag {};
class IndexYTypeTag {};
public:
typedef TypesafeIndex<IndexXTypeTag> X;
typedef TypesafeIndex<IndexYTypeTag> Y;
Matrix(X a_endX, Y a_endY)
: m_endY(a_endX)
, m_matrix(a_endX * a_endY) { /* EMPTY */ }
int& operator()(X a, Y b) {
return m_matrix[a * m_endY + b]; // Implicit conversion to size_t if needed, but only if needed
};
private:
Y m_endY;
std::vector<int> m_matrix;
};
int main() {
typedef Matrix::X X;
typedef Matrix::Y Y;
X endX = X(10); // Explicit construction
Y endY = Y(20);
Matrix matrix(endX, endY);
matrix(X(1),Y(0)) = 1;
matrix(X(0),Y(1)) = 2;
for (X x(1); x < endX; ++x) // Usable as loop variable
{
for (Y y(1); y < endY; ++y)
{
matrix(x,y) = matrix(x-1,y) + matrix(x,y-1); // No additional syntax when doing normal index calculations
//matrix(y+2,x); // Will catch swapped paramters
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment