LINUX.ORG.RU

История изменений

Исправление 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();
};