AshanGimhana's picture
Upload folder using huggingface_hub
9375c9a verified
// Copyright (C) 2006 Davis E. King ([email protected])
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ARRAY2D_KERNEl_1_
#define DLIB_ARRAY2D_KERNEl_1_
#include "array2d_kernel_abstract.h"
#include "../algs.h"
#include "../interfaces/enumerable.h"
#include "../serialize.h"
#include "../geometry/rectangle.h"
namespace dlib
{
template <
typename T,
typename mem_manager = default_memory_manager
>
class array2d : public enumerable<T>
{
/*!
INITIAL VALUE
- nc_ == 0
- nr_ == 0
- data == 0
- at_start_ == true
- cur == 0
- last == 0
CONVENTION
- nc_ == nc()
- nr_ == nc()
- if (data != 0) then
- last == a pointer to the last element in the data array
- data == pointer to an array of nc_*nr_ T objects
- else
- nc_ == 0
- nr_ == 0
- data == 0
- last == 0
- nr_ * nc_ == size()
- if (cur == 0) then
- current_element_valid() == false
- else
- current_element_valid() == true
- *cur == element()
- at_start_ == at_start()
!*/
class row_helper;
public:
// These typedefs are here for backwards compatibility with older versions of dlib.
typedef array2d kernel_1a;
typedef array2d kernel_1a_c;
typedef T type;
typedef mem_manager mem_manager_type;
typedef T* iterator;
typedef const T* const_iterator;
// -----------------------------------
class row
{
/*!
CONVENTION
- nc_ == nc()
- for all x < nc_:
- (*this)[x] == data[x]
!*/
friend class array2d<T,mem_manager>;
friend class row_helper;
public:
long nc (
) const { return nc_; }
const T& operator[] (
long column
) const
{
// make sure requires clause is not broken
DLIB_ASSERT(column < nc() && column >= 0,
"\tconst T& array2d::operator[](long column) const"
<< "\n\tThe column index given must be less than the number of columns."
<< "\n\tthis: " << this
<< "\n\tcolumn: " << column
<< "\n\tnc(): " << nc()
);
return data[column];
}
T& operator[] (
long column
)
{
// make sure requires clause is not broken
DLIB_ASSERT(column < nc() && column >= 0,
"\tT& array2d::operator[](long column)"
<< "\n\tThe column index given must be less than the number of columns."
<< "\n\tthis: " << this
<< "\n\tcolumn: " << column
<< "\n\tnc(): " << nc()
);
return data[column];
}
private:
row(T* data_, long cols) : data(data_), nc_(cols) {}
T* data;
long nc_;
// restricted functions
row(){}
row& operator=(row&);
};
// -----------------------------------
array2d (
) :
data(0),
nc_(0),
nr_(0),
cur(0),
last(0),
at_start_(true)
{
}
array2d(
long rows,
long cols
) :
data(0),
nc_(0),
nr_(0),
cur(0),
last(0),
at_start_(true)
{
// make sure requires clause is not broken
DLIB_ASSERT((cols >= 0 && rows >= 0),
"\t array2d::array2d(long rows, long cols)"
<< "\n\t The array2d can't have negative rows or columns."
<< "\n\t this: " << this
<< "\n\t cols: " << cols
<< "\n\t rows: " << rows
);
set_size(rows,cols);
}
array2d(const array2d&) = delete; // copy constructor
array2d& operator=(const array2d&) = delete; // assignment operator
#ifdef DLIB_HAS_RVALUE_REFERENCES
array2d(array2d&& item) : array2d()
{
swap(item);
}
array2d& operator= (
array2d&& rhs
)
{
swap(rhs);
return *this;
}
#endif
virtual ~array2d (
) { clear(); }
long nc (
) const { return nc_; }
long nr (
) const { return nr_; }
row operator[] (
long row_
)
{
// make sure requires clause is not broken
DLIB_ASSERT(row_ < nr() && row_ >= 0,
"\trow array2d::operator[](long row_)"
<< "\n\tThe row index given must be less than the number of rows."
<< "\n\tthis: " << this
<< "\n\trow_: " << row_
<< "\n\tnr(): " << nr()
);
return row(data+row_*nc_, nc_);
}
const row operator[] (
long row_
) const
{
// make sure requires clause is not broken
DLIB_ASSERT(row_ < nr() && row_ >= 0,
"\tconst row array2d::operator[](long row_) const"
<< "\n\tThe row index given must be less than the number of rows."
<< "\n\tthis: " << this
<< "\n\trow_: " << row_
<< "\n\tnr(): " << nr()
);
return row(data+row_*nc_, nc_);
}
void swap (
array2d& item
)
{
exchange(data,item.data);
exchange(nr_,item.nr_);
exchange(nc_,item.nc_);
exchange(at_start_,item.at_start_);
exchange(cur,item.cur);
exchange(last,item.last);
pool.swap(item.pool);
}
void clear (
)
{
if (data != 0)
{
pool.deallocate_array(data);
nc_ = 0;
nr_ = 0;
data = 0;
at_start_ = true;
cur = 0;
last = 0;
}
}
void set_size (
long rows,
long cols
);
bool at_start (
) const { return at_start_; }
void reset (
) const { at_start_ = true; cur = 0; }
bool current_element_valid (
) const { return (cur != 0); }
const T& element (
) const
{
// make sure requires clause is not broken
DLIB_ASSERT(current_element_valid() == true,
"\tconst T& array2d::element()()"
<< "\n\tYou can only call element() when you are at a valid one."
<< "\n\tthis: " << this
);
return *cur;
}
T& element (
)
{
// make sure requires clause is not broken
DLIB_ASSERT(current_element_valid() == true,
"\tT& array2d::element()()"
<< "\n\tYou can only call element() when you are at a valid one."
<< "\n\tthis: " << this
);
return *cur;
}
bool move_next (
) const
{
if (cur != 0)
{
if (cur != last)
{
++cur;
return true;
}
cur = 0;
return false;
}
else if (at_start_)
{
cur = data;
at_start_ = false;
return (data != 0);
}
else
{
return false;
}
}
size_t size (
) const { return static_cast<size_t>(nc_) * static_cast<size_t>(nr_); }
long width_step (
) const
{
return nc_*sizeof(T);
}
iterator begin()
{
return data;
}
iterator end()
{
return data+size();
}
const_iterator begin() const
{
return data;
}
const_iterator end() const
{
return data+size();
}
private:
T* data;
long nc_;
long nr_;
typename mem_manager::template rebind<T>::other pool;
mutable T* cur;
T* last;
mutable bool at_start_;
};
// ----------------------------------------------------------------------------------------
template <
typename T,
typename mem_manager
>
inline void swap (
array2d<T,mem_manager>& a,
array2d<T,mem_manager>& b
) { a.swap(b); }
template <
typename T,
typename mem_manager
>
void serialize (
const array2d<T,mem_manager>& item,
std::ostream& out
)
{
try
{
// The reason the serialization is a little funny is because we are trying to
// maintain backwards compatibility with an older serialization format used by
// dlib while also encoding things in a way that lets the array2d and matrix
// objects have compatible serialization formats.
serialize(-item.nr(),out);
serialize(-item.nc(),out);
item.reset();
while (item.move_next())
serialize(item.element(),out);
item.reset();
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while serializing object of type array2d");
}
}
template <
typename T,
typename mem_manager
>
void deserialize (
array2d<T,mem_manager>& item,
std::istream& in
)
{
try
{
long nr, nc;
deserialize(nr,in);
deserialize(nc,in);
// this is the newer serialization format
if (nr < 0 || nc < 0)
{
nr *= -1;
nc *= -1;
}
else
{
std::swap(nr,nc);
}
item.set_size(nr,nc);
while (item.move_next())
deserialize(item.element(),in);
item.reset();
}
catch (serialization_error& e)
{
item.clear();
throw serialization_error(e.info + "\n while deserializing object of type array2d");
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename T,
typename mem_manager
>
void array2d<T,mem_manager>::
set_size (
long rows,
long cols
)
{
// make sure requires clause is not broken
DLIB_ASSERT((cols >= 0 && rows >= 0) ,
"\tvoid array2d::set_size(long rows, long cols)"
<< "\n\tThe array2d can't have negative rows or columns."
<< "\n\tthis: " << this
<< "\n\tcols: " << cols
<< "\n\trows: " << rows
);
// set the enumerator back at the start
at_start_ = true;
cur = 0;
// don't do anything if we are already the right size.
if (nc_ == cols && nr_ == rows)
{
return;
}
nc_ = cols;
nr_ = rows;
// free any existing memory
if (data != 0)
{
pool.deallocate_array(data);
data = 0;
}
// now setup this object to have the new size
try
{
if (nr_ > 0)
{
data = pool.allocate_array(nr_*nc_);
last = data + nr_*nc_ - 1;
}
}
catch (...)
{
if (data)
pool.deallocate_array(data);
data = 0;
nc_ = 0;
nr_ = 0;
last = 0;
throw;
}
}
// ----------------------------------------------------------------------------------------
template <typename T, typename MM>
struct is_array2d <array2d<T,MM> >
{
const static bool value = true;
};
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ARRAY2D_KERNEl_1_