
https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Separate tracked_ptr from array2d. * oln/core/2d/array2d.hh (oln::tracked_ptr): Move... * oln/core/internal/tracked_ptr.hh: ...here (new file). * oln/core/2d/image2d.hh (oln::image2d::data_): Adjust type. (oln::image2d(const topo2d&)): New ctor. * tests/image2d.cc: New test. * tests/Makefile.am (check_PROGRAMS): Add image2d. (image2d_SOURCES): New. oln/core/2d/array2d.hh | 169 ------------------------------ oln/core/2d/image2d.hh | 16 ++ oln/core/internal/tracked_ptr.hh | 213 +++++++++++++++++++++++++++++++++++++++ tests/Makefile.am | 2 tests/image2d.cc | 64 +++++++++++ 5 files changed, 293 insertions(+), 171 deletions(-) Index: oln/core/2d/array2d.hh --- oln/core/2d/array2d.hh (revision 599) +++ oln/core/2d/array2d.hh (working copy) @@ -30,181 +30,12 @@ # define OLN_CORE_2D_ARRAY2D_HH # include <cstdlib> -# include <set> # include <mlc/contract.hh> namespace oln { - template <typename T> - struct tracked_ptr - { - typedef tracked_ptr<T> self_t; - typedef std::set<self_t*> holders_t; - - T* ptr_; - holders_t* holders_; - - /// Coercion towards Boolean (for arithmetical tests). - operator bool() const - { - invariant_(); - return ptr_ != 0; - } - - /// Negation (for arithmetical tests). - bool operator not() const - { - invariant_(); - return not bool(*this); - } - - /*! \brief Mimics the behavior of op-> for a pointer in the const case. - ** - ** \invariant Pointer proxy exists. - */ - const T*const operator->() const - { - invariant_(); - precondition(ptr_ != 0); - return ptr_; - } - - /*! \brief Mimics the behavior of op-> for a pointer in the mutable case. - ** - ** \invariant Pointer proxy exists. - */ - T*const operator->() - { - invariant_(); - precondition(ptr_ != 0); - return ptr_; - } - - /// Ctor. - tracked_ptr() : - ptr_(0), - holders_(0) - { - invariant_(); - } - - /// Ctor. - tracked_ptr(T* ptr) : - ptr_(ptr) - { - if (ptr == 0) - holders_ = 0; - else - { - holders_ = new holders_t; - holders_->insert(this); - } - invariant_(); - } - - /// Cpy ctor. - tracked_ptr(const self_t& rhs) : - ptr_(rhs.ptr_), - holders_(rhs.holders_) - { - rhs.invariant_(); - if (ptr_ != 0) - holders_->insert(this); - invariant_(); - } - - /// Assignment. - self_t& operator=(const self_t& rhs) - { - invariant_(); - rhs.invariant_(); - if (&rhs == this or rhs.ptr_ == ptr_) - // no-op - return *this; - clean_(); - ptr_ = rhs.ptr_; - holders_ = rhs.holders_; - holders_->insert(this); - return *this; - } - - /// Assignment. - self_t& operator=(T* ptr) - { - invariant_(); - if (ptr == ptr_) - // no-op - return *this; - clean_(); - ptr_ = ptr; - if (ptr == 0) - holders_ = 0; - else - { - holders_ = new holders_t; - holders_->insert(this); - } - return *this; - } - - /// Dtor. - ~tracked_ptr() - { - clean_(); - } - - void invariant_() const - { - invariant((ptr_ and holders_) or (not ptr_ and not holders_)); - if (ptr_ == 0) - return; - invariant(holders_->size() > 0); - self_t* this_ = const_cast<self_t*>(this); - invariant(holders_->find(this_) != holders_->end()); - typename holders_t::const_iterator i; - for (i = holders_->begin(); i != holders_->end(); ++i) - invariant((*i)->ptr_ == ptr_); - } - - void clean_() - { - invariant_(); - if (ptr_ == 0) - // no-op - return; - if (holders_->size() == 1) - { - delete ptr_; - delete holders_; - } - else - holders_->erase(this); - ptr_ = 0; - holders_ = 0; - invariant_(); - } - - friend std::ostream& operator<<(std::ostream& ostr, const self_t& tp) - { - ostr << "tracked_ptr @ " << (&tp) - << " { ptr = " << tp.ptr_ - << " / holders = "; - if (tp.holders_ == 0) - ostr << "0"; - else - { - typename holders_t::const_iterator i; - for (i = tp.holders_->begin(); i != tp.holders_->end(); ++i) - ostr << (*i) << ' '; - } - ostr << " }"; - return ostr; - } - }; - - /// General 2D array class. template <typename value_t, typename coord_t = int> class array2d Index: oln/core/internal/tracked_ptr.hh --- oln/core/internal/tracked_ptr.hh (revision 0) +++ oln/core/internal/tracked_ptr.hh (revision 0) @@ -0,0 +1,213 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef OLN_CORE_INTERNAL_TRACKED_PTR_HH +# define OLN_CORE_INTERNAL_TRACKED_PTR_HH + +# include <set> + + +namespace oln +{ + + namespace internal + { + + template <typename T> + struct tracked_ptr + { + typedef tracked_ptr<T> self_t; + typedef std::set<self_t*> holders_t; + + T* ptr_; + holders_t* holders_; + + /// Coercion towards Boolean (for arithmetical tests). + operator bool() const + { + invariant_(); + return ptr_ != 0; + } + + /// Negation (for arithmetical tests). + bool operator not() const + { + invariant_(); + return not bool(*this); + } + + /*! \brief Mimics the behavior of op-> for a pointer in the const case. + ** + ** \invariant Pointer proxy exists. + */ + const T*const operator->() const + { + invariant_(); + precondition(ptr_ != 0); + return ptr_; + } + + /*! \brief Mimics the behavior of op-> for a pointer in the mutable case. + ** + ** \invariant Pointer proxy exists. + */ + T*const operator->() + { + invariant_(); + precondition(ptr_ != 0); + return ptr_; + } + + /// Ctor. + tracked_ptr() : + ptr_(0), + holders_(0) + { + invariant_(); + } + + /// Ctor. + tracked_ptr(T* ptr) : + ptr_(ptr) + { + if (ptr == 0) + holders_ = 0; + else + { + holders_ = new holders_t; + holders_->insert(this); + } + invariant_(); + } + + /// Cpy ctor. + tracked_ptr(const self_t& rhs) : + ptr_(rhs.ptr_), + holders_(rhs.holders_) + { + rhs.invariant_(); + if (ptr_ != 0) + holders_->insert(this); + invariant_(); + } + + /// Assignment. + self_t& operator=(const self_t& rhs) + { + invariant_(); + rhs.invariant_(); + if (&rhs == this or rhs.ptr_ == ptr_) + // no-op + return *this; + clean_(); + ptr_ = rhs.ptr_; + holders_ = rhs.holders_; + holders_->insert(this); + return *this; + } + + /// Assignment. + self_t& operator=(T* ptr) + { + invariant_(); + if (ptr == ptr_) + // no-op + return *this; + clean_(); + ptr_ = ptr; + if (ptr == 0) + holders_ = 0; + else + { + holders_ = new holders_t; + holders_->insert(this); + } + return *this; + } + + /// Dtor. + ~tracked_ptr() + { + clean_(); + } + + void invariant_() const + { + invariant((ptr_ and holders_) or (not ptr_ and not holders_)); + if (ptr_ == 0) + return; + invariant(holders_->size() > 0); + self_t* this_ = const_cast<self_t*>(this); + invariant(holders_->find(this_) != holders_->end()); + typename holders_t::const_iterator i; + for (i = holders_->begin(); i != holders_->end(); ++i) + invariant((*i)->ptr_ == ptr_); + } + + void clean_() + { + invariant_(); + if (ptr_ == 0) + // no-op + return; + if (holders_->size() == 1) + { + delete ptr_; + delete holders_; + } + else + holders_->erase(this); + ptr_ = 0; + holders_ = 0; + invariant_(); + } + + friend std::ostream& operator<<(std::ostream& ostr, const self_t& tp) + { + ostr << "tracked_ptr @ " << (&tp) + << " { ptr = " << tp.ptr_ + << " / holders = "; + if (tp.holders_ == 0) + ostr << "0"; + else + { + typename holders_t::const_iterator i; + for (i = tp.holders_->begin(); i != tp.holders_->end(); ++i) + ostr << (*i) << ' '; + } + ostr << " }"; + return ostr; + } + }; + + + } // end of namespace oln::internal + +} // end of namespace oln + + +#endif // ! OLN_CORE_INTERNAL_TRACKED_PTR_HH Index: oln/core/2d/image2d.hh --- oln/core/2d/image2d.hh (revision 599) +++ oln/core/2d/image2d.hh (working copy) @@ -31,6 +31,7 @@ # include <oln/core/image_entry.hh> # include <oln/core/2d/array2d.hh> +# include <oln/core/internal/tracked_ptr.hh> namespace oln @@ -44,6 +45,7 @@ template <typename T> struct vtypes< image2d<T> > { + // FIXME: or `typedef topo2d topo_type;' ? typedef topo_lbbox_<point2d> topo_type; typedef grid2d grid_type; @@ -78,7 +80,7 @@ public: - /// Ctor. + /// Ctor using sizes. image2d(unsigned nrows, unsigned ncols, unsigned border = 2) : topo_(bbox2d(point2d(0, 0), point2d(nrows-1, ncols-1)), @@ -87,6 +89,16 @@ { } + /// Ctor using an existing topology. + image2d(const topo2d& topo) + : topo_(topo), + data_(new array_t(topo.bbox().pmin().row(), + topo.bbox().pmin().col(), + topo.bbox().pmax().row(), + topo.bbox().pmax().col())) + { + } + const topo2d& impl_topo() const { return topo_; @@ -109,7 +121,7 @@ private: topo2d topo_; - tracked_ptr<array_t> data_; + internal::tracked_ptr<array_t> data_; }; Index: tests/image2d.cc --- tests/image2d.cc (revision 0) +++ tests/image2d.cc (revision 0) @@ -0,0 +1,64 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/// Test oln::image2d. + +#include <cassert> +// FIXME: We should not include oln/basics2d.hh, but +// oln/core/2d/image2d.hh (and oln/core/2d/neigh2d.hh ?). +#include <oln/basics2d.hh> +#include <oln/level/fill.hh> + +int +main() +{ + // Fill a 2-d image using its iterator. + oln::image2d<char> ima1(3, 3); + oln_type_of_(oln::image2d<char>, piter) p1(ima1.topo()); + for_all(p1) + ima1(p1) = 1; + + // Fill a 2-d image using a classic loop. + oln::image2d<int> ima2(ima1.topo()); + for (unsigned i = 0; i < 3; ++i) + for (unsigned j = 0; j < 3; ++j) + ima2(oln::point2d(i, j)) = 2; + + // Fill a 2-d image using the routine oln::level::fill. + oln::image2d<long> ima3(ima1.topo()); + oln::level::fill(ima3, 3); + + + // Add the three images. + oln::image2d<long> sum(ima1.topo()); + oln_type_of_(oln::image2d<long>, piter) p(sum.topo()); + for_all(p) + sum(p) = ima1(p) + ima2(p) + ima3(p); + // And check the sum. + for_all(p) + assert(sum(p) == 6); +} Index: tests/Makefile.am --- tests/Makefile.am (revision 599) +++ tests/Makefile.am (working copy) @@ -18,6 +18,7 @@ check_PROGRAMS = \ grid \ image_entry \ + image2d \ npoints \ \ identity_morpher \ @@ -29,6 +30,7 @@ # Images and auxiliary structures. grid_SOURCES = grid.cc image_entry_SOURCES = image_entry.cc +image2d_SOURCES = image2d.cc npoints_SOURCES = npoints.cc # Morphers.