Created
July 3, 2019 16:24
-
-
Save Const-me/7aee0ef4087d250cc9b82463988ecafc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <assert.h> | |
#include <vector> | |
#include <algorithm> | |
// 2D vector of integers | |
struct Vector2i | |
{ | |
int x, y; | |
Vector2i() = default; | |
Vector2i( int _x, int _y ) : x( _x ), y( _y ) { } | |
Vector2i operator+( const Vector2i that ) const | |
{ | |
// C++ books say "pass by const reference", but on modern systems small structures normally passed in registers, faster. | |
return Vector2i{ x + that.x, y + that.y }; | |
} | |
void operator+=( const Vector2i that ) | |
{ | |
x += that.x; | |
y += that.y; | |
// C++ books say "return *this", but I don't think code like `a += b += c` should compile. Deliberately making it fail. | |
} | |
// Implement whatever operators you need for them | |
}; | |
// 2D grid of items, where items are kept in continuous block of RAM. | |
// For very small items like bytes, you'd probably want line padding. For very large ones, you might want vector of vectors, one per line. Both are performance optimizations, you might not need either of them, ever. | |
template<class T> | |
class Grid | |
{ | |
Vector2i size; | |
std::vector<T> data; | |
size_t getIndex( const Vector2i pos ) const | |
{ | |
assert( pos.x >= 0 && pos.y >= 0 && pos.x < size.x && pos.y < size.y ); | |
return (size_t)pos.y * (size_t)size.x + (size_t)pos.x; | |
} | |
public: | |
Grid() | |
{ | |
size.x = size.y = 0; | |
} | |
void resize( const Vector2i newSize ) | |
{ | |
assert( newSize.x >= 0 && newSize.y >= 0 ); | |
const size_t newLength = (size_t)newSize.x * (size_t)newSize.y; | |
data.resize( newLength ); | |
size = newSize; | |
} | |
bool empty() const | |
{ | |
return data.empty(); | |
} | |
void clear() | |
{ | |
data.clear(); | |
size.x = size.y = 0; | |
} | |
Vector2i getSize() const { return size; } | |
// Access an item by 2D element index | |
T& operator[] ( const Vector2i pos ) | |
{ | |
return data[ getIndex( pos ) ]; | |
} | |
// Access an item by 2D element index, readonly version | |
const T& operator[] ( const Vector2i pos ) const | |
{ | |
return data[ getIndex( pos ) ]; | |
} | |
// Set the complete grid to the same value | |
void fillGrid( const T& value ) | |
{ | |
std::fill( data.begin(), data.end(), value ); | |
} | |
// Set a complete horizontal line to the same value | |
void fillScanline( int y, const T& value ) | |
{ | |
assert( y >= 0 && y < size.y ); | |
auto iter = data.begin() + (size_t)y * (size_t)size.x; | |
std::fill( iter, iter + size.x, value ); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@sdegutis Something like this: