Index: ChangeLog
from Simon Odou <simon(a)lrde.epita.fr>
* oln/core/1d/array1d.hh: New.
* oln/core/2d/array2d.hh: Fix a missing destructor.
* oln/core/3d/array3d.hh: New.
1d/array1d.hh | 156 +++++++++++++++++++++++++++++++++++++++++++
2d/array2d.hh | 8 +-
3d/array3d.hh | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 371 insertions(+), 1 deletion(-)
Index: oln/core/1d/array1d.hh
--- oln/core/1d/array1d.hh (revision 0)
+++ oln/core/1d/array1d.hh (revision 0)
@@ -0,0 +1,156 @@
+#ifndef OLENA_CORE_1D_ARRAY1D_HH
+# define OLENA_CORE_1D_ARRAY1D_HH
+
+
+# include <oln/core/abstract/data_storage.hh>
+# include <oln/core/1d/size1d.hh>
+# include <oln/core/1d/point1d.hh>
+
+namespace oln {
+
+
+ template <typename T> struct array1d;
+ template <typename T>
+ struct category_type< array1d<T> > { typedef cat::data_storage ret; };
+
+
+ template <typename T>
+ struct props < cat::data_storage, array1d<T> > // FIXME: add inheritance
+ {
+ typedef size1d size_type;
+ typedef point1d point_type;
+ typedef T data_type;
+ };
+
+
+ template <typename T>
+ class array1d : public abstract::data_storage< array1d<T> >
+ {
+
+ public:
+
+ array1d() :
+ buffer_(0),
+ size_()
+ {
+ this->exact_ptr = this;
+ invariant_();
+ }
+
+ // w/o impl
+ array1d(const array1d&);
+ void operator=(const array1d&);
+
+
+ array1d(const size1d& s) :
+ buffer_(0),
+ size_()
+ {
+ this->exact_ptr = this;
+ this->resize(s);
+ }
+
+ ~array1d()
+ {
+ this->impl_clear_data();
+ }
+
+ bool impl_has_data() const
+ {
+ invariant_();
+ return buffer_ != 0;
+ }
+
+ void impl_clear_data()
+ {
+ invariant_();
+ if (this->has_data())
+ {
+ // buffer
+ delete[] buffer_;
+ buffer_ = 0;
+ // size
+ size_ = size1d();
+ }
+ invariant_();
+ }
+
+ const size1d& size() const
+ {
+ return size_;
+ }
+
+ void impl_resize(const size1d& s)
+ {
+ precondition(s.nindices() > 0 and
+ s.border() >= 0);
+ invariant_();
+ this->clear_data();
+ size_ = s;
+ size_t nelts_eff = size_.nindices() + 2 * size_.border();
+ buffer_ = new T[nelts_eff];
+ invariant_();
+ }
+
+ unsigned long impl_npoints() const
+ {
+ return size_.npoints();
+ }
+
+ bool impl_hold(const point1d& p) const
+ {
+ return
+ p.index() >= 0 and
+ p.index() < size_.nindices();
+ }
+
+ bool impl_hold_large(const point1d& p) const
+ {
+ return
+ p.index() >= - size_.border() and
+ p.index() < size_.nindices() + size_.border();
+ }
+
+ const T impl_get(const point1d& p) const
+ {
+ invariant_();
+ return buffer_[p.index()];
+ }
+
+ void impl_set(const point1d& p, const T& v)
+ {
+ invariant_();
+ buffer_[p.index()] = v;
+ }
+
+ void impl_set_data(const T& v)
+ {
+ invariant_();
+ const size_t len = size_.nindices() + 2 * size_.border();
+ T* p = buffer_;
+ for (size_t i = 0; i < len; ++i)
+ *p++ = v;
+ }
+
+ private:
+
+ T* buffer_;
+ size1d size_;
+
+ void invariant_() const
+ {
+ invariant((buffer_ != 0 and
+ size_.nindices() > 0 and
+ size_.border() >= 0)
+ or
+ (buffer_ == 0 and
+ size_.nindices() == 0 and
+ size_.border() == 0));
+ }
+
+ };
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_1D_ARRAY1D_HH
Index: oln/core/2d/array2d.hh
--- oln/core/2d/array2d.hh (revision 11)
+++ oln/core/2d/array2d.hh (working copy)
@@ -10,7 +10,8 @@
template <typename T> struct array2d;
- template <typename T> struct category_type< array2d<T> > { typedef
cat::data_storage ret; };
+ template <typename T>
+ struct category_type< array2d<T> > { typedef cat::data_storage ret; };
template <typename T>
@@ -51,6 +52,11 @@
this->resize(s);
}
+ ~array2d()
+ {
+ this->impl_clear_data();
+ }
+
bool impl_has_data() const
{
invariant_();
Index: oln/core/3d/array3d.hh
--- oln/core/3d/array3d.hh (revision 0)
+++ oln/core/3d/array3d.hh (revision 0)
@@ -0,0 +1,208 @@
+#ifndef OLENA_CORE_3D_ARRAY3D_HH
+# define OLENA_CORE_3D_ARRAY3D_HH
+
+
+# include <oln/core/abstract/data_storage.hh>
+# include <oln/core/3d/size3d.hh>
+# include <oln/core/3d/point3d.hh>
+
+namespace oln {
+
+
+ template <typename T> struct array3d;
+ template <typename T>
+ struct category_type< array3d<T> > { typedef cat::data_storage ret; };
+
+
+ template <typename T>
+ struct props < cat::data_storage, array3d<T> > // FIXME: add inheritance
+ {
+ typedef size3d size_type;
+ typedef point3d point_type;
+ typedef T data_type;
+ };
+
+
+ template <typename T>
+ class array3d : public abstract::data_storage< array3d<T> >
+ {
+
+ public:
+
+ array3d() :
+ buffer_(0),
+ array_(0),
+ array2_(0),
+ size_()
+ {
+ this->exact_ptr = this;
+ invariant_();
+ }
+
+ // w/o impl
+ array3d(const array3d&);
+ void operator=(const array3d&);
+
+
+ array3d(const size3d& s) :
+ buffer_(0),
+ array_(0),
+ array2_(0),
+ size_()
+ {
+ this->exact_ptr = this;
+ this->resize(s);
+ }
+
+ ~array3d()
+ {
+ this->impl_clear_data();
+ }
+
+ bool impl_has_data() const
+ {
+ invariant_();
+ return buffer_ != 0;
+ }
+
+ void impl_clear_data()
+ {
+ invariant_();
+ if (this->has_data())
+ {
+ // buffer
+ delete[] buffer_;
+ buffer_ = 0;
+ // array2
+ delete[] array2_;
+ array2_ = 0;
+ // array
+ array_ -= size_.border();
+ delete[] array_;
+ array_ = 0;
+ // size
+ size_ = size3d();
+ }
+ invariant_();
+ }
+
+ const size3d& size() const
+ {
+ return size_;
+ }
+
+ void impl_resize(const size3d& s)
+ {
+ precondition(s.nslices() > 0 and
+ s.nrows() > 0 and
+ s.ncols() > 0 and
+ s.border() >= 0);
+ invariant_();
+ this->clear_data();
+ size_ = s;
+
+ size_t nslices_eff = size_.nslices() + 2 * size_.border();
+ size_t nrows_eff = size_.nrows() + 2 * size_.border();
+ size_t ncols_eff = size_.ncols() + 2 * size_.border();
+ size_t nelts_eff = nslices_eff * nrows_eff * ncols_eff;
+
+ buffer_ = new T[nelts_eff];
+ array_ = new T**[nslices_eff];
+ array2_ = new T*[nslices_eff * nrows_eff];
+
+ T* buf = buffer_ + size_.border();
+ for (size_t slice = 0; slice < nslices_eff; ++slice)
+ {
+ T** a2 = array2_ + slice * nrows_eff;
+ array[slice] = a2 + size_.border();
+ for (size_t row = 0; row < nrows_eff; ++row)
+ {
+ a2[row] = buf;
+ buf += ncols_eff;
+ }
+ }
+ array_ += size_.border();
+ invariant_();
+ }
+
+ unsigned long impl_npoints() const
+ {
+ return size_.npoints();
+ }
+
+ bool impl_hold(const point3d& p) const
+ {
+ return
+ p.slice() >= 0 and
+ p.slice() < size_.nslices() and
+ p.row() >= 0 and
+ p.row() < size_.nrows() and
+ p.col() >= 0 and
+ p.col() < size_.ncols();
+ }
+
+ bool impl_hold_large(const point3d& p) const
+ {
+ return
+ p.slice() >= - size_.border() and
+ p.slice() < size_.nslices() + size_.border() and
+ p.row() >= - size_.border() and
+ p.row() < size_.nrows() + size_.border() and
+ p.col() >= - size_.border() and
+ p.col() < size_.ncols() + size_.border();
+ }
+
+ const T impl_get(const point3d& p) const
+ {
+ invariant_();
+ return array_[p.slice()][p.row()][p.col()];
+ }
+
+ void impl_set(const point3d& p, const T& v)
+ {
+ invariant_();
+ array_[p.slice()][p.row()][p.col()] = v;
+ }
+
+ void impl_set_data(const T& v)
+ {
+ invariant_();
+ const size_t nslices_eff = size_.nslices() + 2 * size_.border();
+ const size_t nrows_eff = size_.nrows() + 2 * size_.border();
+ const size_t ncols_eff = size_.ncols() + 2 * size_.border();
+ const size_t len = nslices_eff * nrows_eff * ncols_eff;
+ T* p = buffer_;
+ for (size_t i = 0; i < len; ++i)
+ *p++ = v;
+ }
+
+ private:
+
+ T* buffer_;
+ T** array2_;
+ T*** array_;
+ size3d size_;
+
+ void invariant_() const
+ {
+ invariant((buffer_ != 0 and
+ array_ != 0 and
+ size_.nslices() > 0 and
+ size_.nrows() > 0 and
+ size_.ncols() > 0 and
+ size_.border() >= 0)
+ or
+ (buffer_ == 0 and
+ array_ == 0 and
+ size_.nslices() == 0 and
+ size_.nrows() == 0 and
+ size_.ncols() == 0 and
+ size_.border() == 0));
+ }
+
+ };
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_3D_ARRAY3D_HH