Исправление AntonI, (текущая версия) :
Не, это уже решение, надо поставить задачу и обозначить узкие места(узкие в плане дизайна). Другое дело, если достаточно хорошо тут сформулировать задачу, то и решение может оказаться очевидным.
Дык если бы я бы мог это сделать то я бы и тред не создавал!
Давай я попробую набросать интерфейс, а ты покритикуешь?;-)
// это какой то D-мерный массив из ячеек типа T
// предполагается что таких массивов может быть много разных,
// но они все имеют унифицированный интерфейс
template <typename T, int D> Arr{
...
public:
size_t size() const;
struct Index; // обеспечивает быстрый доступ к произвольному элементу
T& operator [](Index); // вот его можно использовать
Index get_index(Ind<D>) const; // так их можно создавать
Index get_index(size_t i) const; // или так
struct StencilPoint; // это точка шаблона (сдвиг относительно ячейки)
StencilPoint get_stencil_point(Ind<D> delta);
struct Cell: protected Index{ // дает доступ к ячейке и ее окружению
protected:
Arr *arr;
public:
T& operator *();
T* operator ->();
Ind<D> get_pos() const;
// битовая маска указывающая на принадлежность к границе
// по два бита на ось, первый слева второй справа
uint32_t is_bound() const;
// медленный доступ к соседним ячейкам
// это очень удобный классический интерфейс, но
// непонятно как сигнализировать о выходе за границу
T& operator [](Ind<D> delta);
// быстрый доступ к соседним ячейкам
// но проблема с сигнализацией о выходе за границу та же
T& operator [](StencilPoint delta);
// проверка выхода за границу
// с точки зрения производительности лучше
// бы ее объединить с доступом к соседней ячейке
bool check_out(Ind<D> delta);
bool check_out(StencilPoint delta);
// это неуклюжая попытка такого объединения
// возвращается битовая маска в которой отмечены
// промахи по осям (по два бита на ось)
uint32_t get_nb(Ind<D> delta, T** ptr);
uint32_t get_nb(StencilPoint delta, T** ptr);
};
Cell get_cell(Ind<D>); // доступ к произвольной ячейке
Cell get_cell(Index);
struct Iterator: public Cell{
void operator ++ (); // для синтаксического сахара
void operator = (size_t i); // для обхода обычными циклами
};
Iterator begin();
Iterator end();
};
Исходная версия AntonI, :
Не, это уже решение, надо поставить задачу и обозначить узкие места(узкие в плане дизайна). Другое дело, если достаточно хорошо тут сформулировать задачу, то и решение может оказаться очевидным.
Дык если бы я бы мог это сделать то я бы и тред не создавал!;-)
Давай я попробую набросать интерфейс, а ты покритикуешь
// это какой то D-мерный массив из ячеек типа T
// предполагается что таких массивов может быть много разных,
// но они все имеют унифицированный интерфейс
template <typename T, int D> Arr{
...
public:
size_t size() const;
struct Index; // обеспечивает быстрый доступ к произвольному элементу
T& operator [](Index); // вот его можно использовать
Index get_index(Ind<D>) const; // так их можно создавать
Index get_index(size_t i) const; // или так
struct StencilPoint; // это точка шаблона (сдвиг относительно ячейки)
StencilPoint get_stencil_point(Ind<D> delta);
struct Cell: protected Index{ // дает доступ к ячейке и ее окружению
protected:
Arr *arr;
public:
T& operator *();
T* operator ->();
Ind<D> get_pos() const;
// битовая маска указывающая на принадлежность к границе
// по два бита на ось, первый слева второй справа
uint32_t is_bound() const;
// медленный доступ к соседним ячейкам
// это очень удобный классический интерфейс, но
// непонятно как сигнализировать о выходе за границу
T& operator [](Ind<D> delta);
// быстрый доступ к соседним ячейкам
// но проблема с сигнализацией о выходе за границу та же
T& operator [](StencilPoint delta);
// проверка выхода за границу
// с точки зрения производительности лучше
// бы ее объединить с доступом к соседней ячейке
bool check_out(Ind<D> delta);
bool check_out(StencilPoint delta);
// это неуклюжая попытка такого объединения
// возвращается битовая маска в которой отмечены
// промахи по осям (по два бита на ось)
uint32_t get_nb(Ind<D> delta, T** ptr);
uint32_t get_nb(StencilPoint delta, T** ptr);
};
Cell get_cell(Ind<D>); // доступ к произвольной ячейке
Cell get_cell(Index);
struct Iterator: public Cell{
void operator ++ (); // для синтаксического сахара
void operator = (size_t i); // для обхода обычными циклами
};
Iterator begin();
Iterator end();
};