Commit 03d01fa8 authored by Roland Levillain's avatar Roland Levillain
Browse files

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.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@600 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 2265fb70
2006-10-02 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.
2006-10-02 Roland Levillain <roland@lrde.epita.fr>
Fix the inheritance of oln::point2d_ and oln::dpoint2d_.
......
......@@ -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
......
......@@ -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 @@ namespace oln
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 @@ namespace oln
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 @@ namespace oln
{
}
/// 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 @@ namespace oln
private:
topo2d topo_;
tracked_ptr<array_t> data_;
internal::tracked_ptr<array_t> data_;
};
......
// 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
......@@ -18,6 +18,7 @@ CXXFLAGS += $(TESTS_CXXFLAGS)
check_PROGRAMS = \
grid \
image_entry \
image2d \
npoints \
\
identity_morpher \
......@@ -29,6 +30,7 @@ check_PROGRAMS = \
# Images and auxiliary structures.
grid_SOURCES = grid.cc
image_entry_SOURCES = image_entry.cc
image2d_SOURCES = image2d.cc
npoints_SOURCES = npoints.cc
# Morphers.
......
// 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);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment