https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from Roland Levillain <roland(a)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.