Commit e79fdf8e authored by Thierry Geraud's avatar Thierry Geraud
Browse files

2006-09-27 Thierry GERAUD <theo@tegucigalpa.lrde.epita.fr>

	Add array2d and tracked_ptr.
	
	* oln/core/2d/array2d.hh: New.
	This file also provides the tracked_ptr class which should be
	moved later in a more appropriate file.
	* oln/core/2d/image2d.hh (lvalue_type, is_mutable_type): Add.
	(data_): New attribute.
	(impl_op_read): Update; code is no more fake.
	(impl_op_readwrite): New.
	(image2d): Update.
	* oln/Makefile.am (nobase_oln_HEADERS): Update; remove
	the core/2d/grid2d.hh duplicate.



git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@578 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent bed298a1
2006-09-27 Thierry GERAUD <theo@tegucigalpa.lrde.epita.fr>
Add array2d and tracked_ptr.
* oln/core/2d/array2d.hh: New.
This file also provides the tracked_ptr class which should be
moved later in a more appropriate file.
* oln/core/2d/image2d.hh (lvalue_type, is_mutable_type): Add.
(data_): New attribute.
(impl_op_read): Update; code is no more fake.
(impl_op_readwrite): New.
(image2d): Update.
* oln/Makefile.am (nobase_oln_HEADERS): Update; remove
the core/2d/grid2d.hh duplicate.
2006-09-27 Roland Levillain <roland@lrde.epita.fr>
* tests/Makefile.am (AM_CXXFLAGS): Set to -O0 -ggdb.
......
......@@ -15,8 +15,8 @@ nobase_oln_HEADERS = \
\
core/1d/grid1d.hh \
\
core/2d/grid2d.hh \
core/2d/aliases.hh \
core/2d/array2d.hh \
core/2d/dpoint2d.hh \
core/2d/grid2d.hh \
core/2d/image2d.hh \
......
// Copyright (C) 2001, 2003, 2004, 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 OLENA_CORE_2D_ARRAY2D_HH
# define OLENA_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
{
public:
/// Ctor.
array2d(coord_t imin, coord_t jmin,
coord_t imax, coord_t jmax) :
imin_(imin),
jmin_(jmin),
imax_(imax),
jmax_(jmax)
{
precondition(imax >= imin and jmax >= jmin);
ilen_ = imax - imin + 1;
jlen_ = jmax - jmin + 1;
allocate_();
}
/// Ctor.
array2d(coord_t ilen, coord_t jlen) :
imin_(0),
jmin_(0),
ilen_(ilen),
jlen_(jlen)
{
precondition(ilen > 0 and jlen > 0);
imax_ = imin_ + ilen_;
jmax_ = jmin_ + ilen_;
allocate_();
}
/// Dtor.
~array2d()
{
deallocate_();
}
value_t operator()(coord_t i, coord_t j) const
{
precondition(has(i, j));
return array_[i][j];
}
value_t& operator()(coord_t i, coord_t j)
{
precondition(has(i, j));
return array_[i][j];
}
bool has(coord_t i, coord_t j) const
{
return
i >= imin_ and i <= imax_ and
j >= jmin_ and j <= jmax_;
}
size_t memsize() const
{
return
// buffer_
size_t(ilen_) * size_t(jlen_) * sizeof(value_t)
+
// array_
size_t(ilen_) * sizeof(value_t*);
}
protected:
coord_t imin_, jmin_, imax_, jmax_;
coord_t ilen_, jlen_;
value_t* buffer_;
value_t** array_;
private:
void allocate_()
{
buffer_ = new value_t[size_t(ilen_) * size_t(jlen_)];
array_ = new value_t*[size_t(ilen_)];
value_t* buf = buffer_ - jmin_;
for (coord_t i = 0; i < ilen_; ++i)
{
array_[i] = buf;
buf += jlen_;
}
array_ -= imin_;
}
void deallocate_()
{
precondition(buffer_ != 0 and array_ != 0);
delete[] buffer_;
buffer_ = 0; // safety
array_ += imin_;
delete[] array_;
array_ = 0; // safety
}
};
} // end of namespace oln
#endif // ! OLENA_CORE_2D_ARRAY2D_HH
......@@ -30,6 +30,7 @@
# define OLENA_CORE_2D_IMAGE2D_HH
# include <oln/core/image_entry.hh>
# include <oln/core/2d/array2d.hh>
namespace oln
......@@ -52,6 +53,8 @@ namespace oln
typedef bkd_piter_bbox_<topo_type> bkd_piter_type;
typedef T value_type;
typedef T lvalue_type;
typedef mlc::true_ is_mutable_type;
typedef image2d<T> real_type;
};
......@@ -71,12 +74,16 @@ namespace oln
class image2d : public image_entry< image2d<T> >
{
typedef image2d<T> self_t;
typedef array2d<T> array_t;
public:
/// Ctor.
image2d(unsigned nrows, unsigned ncols, unsigned border = 2)
: topo_( bbox2d( point2d(0,0), point2d(nrows-1, ncols-1)), border )
: topo_(bbox2d(point2d(0, 0),
point2d(nrows-1, ncols-1)),
border),
data_(new array_t(0, 0, nrows-1, ncols-1))
{
}
......@@ -87,19 +94,22 @@ namespace oln
T impl_op_read(const point2d& p) const
{
return (T)(void*)this;
// static T val_;
// return ++val_;
precondition(data_ != 0);
precondition(topo_.has_large(p));
return data_->operator()(p.row(), p.col());
}
bool impl_has(const point2d& p) const
T& impl_op_readwrite(const point2d& p)
{
return true;
precondition(data_ != 0);
precondition(topo_.has_large(p));
return data_->operator()(p.row(), p.col());
}
private:
topo2d topo_;
tracked_ptr<array_t> data_;
};
......
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