mirror of https://github.com/CGAL/cgal
234 lines
4.3 KiB
C++
234 lines
4.3 KiB
C++
/*
|
|
*
|
|
* Template Numerical Toolkit (TNT)
|
|
*
|
|
* Mathematical and Computational Sciences Division
|
|
* National Institute of Technology,
|
|
* Gaithersburg, MD USA
|
|
*
|
|
*
|
|
* This software was developed at the National Institute of Standards and
|
|
* Technology (NIST) by employees of the Federal Government in the course
|
|
* of their official duties. Pursuant to title 17 Section 105 of the
|
|
* United States Code, this software is not subject to copyright protection
|
|
* and is in the public domain. NIST assumes no responsibility whatsoever for
|
|
* its use by other parties, and makes no guarantees, expressed or implied,
|
|
* about its quality, reliability, or any other characteristic.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#ifndef CGAL_TNT_I_REFVEC_H
|
|
#define CGAL_TNT_I_REFVEC_H
|
|
#include <CGAL/PDB/basic.h>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
|
|
|
|
CGAL_TNT_BEGIN_NAMESPACE
|
|
|
|
/*
|
|
Internal representation of ref-counted array. The TNT
|
|
arrays all use this building block.
|
|
|
|
<p>
|
|
If an array block is created by TNT, then every time
|
|
an assignment is made, the left-hand-side reference
|
|
is decreased by one, and the right-hand-side refernce
|
|
count is increased by one. If the array block was
|
|
external to TNT, the refernce count is a NULL pointer
|
|
regardless of how many references are made, since the
|
|
memory is not freed by TNT.
|
|
|
|
|
|
|
|
*/
|
|
template <class T>
|
|
class i_refvec
|
|
{
|
|
|
|
|
|
private:
|
|
T* data_;
|
|
int *ref_count_;
|
|
|
|
|
|
public:
|
|
|
|
i_refvec();
|
|
explicit i_refvec(int n);
|
|
inline i_refvec(T* data);
|
|
inline i_refvec(const i_refvec &v);
|
|
inline T* begin();
|
|
inline const T* begin() const;
|
|
inline T& operator[](int i);
|
|
inline const T& operator[](int i) const;
|
|
inline i_refvec<T> & operator=(const i_refvec<T> &V);
|
|
void copy_(T* p, const T* q, const T* e);
|
|
void set_(T* p, const T* b, const T* e);
|
|
inline int ref_count() const;
|
|
inline int is_null() const;
|
|
inline void destroy();
|
|
~i_refvec();
|
|
|
|
};
|
|
|
|
template <class T>
|
|
void i_refvec<T>::copy_(T* p, const T* q, const T* e)
|
|
{
|
|
for (T* t=p; q<e; t++, q++)
|
|
*t= *q;
|
|
}
|
|
|
|
template <class T>
|
|
i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {}
|
|
|
|
/**
|
|
In case n is 0 or negative, it does NOT call new.
|
|
*/
|
|
template <class T>
|
|
i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL)
|
|
{
|
|
if (n >= 1)
|
|
{
|
|
#ifdef CGAL_TNT_DEBUG
|
|
std::cout << "new data storage.\n";
|
|
#endif
|
|
data_ = new T[n];
|
|
ref_count_ = new int;
|
|
*ref_count_ = 1;
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
inline i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_),
|
|
ref_count_(V.ref_count_)
|
|
{
|
|
if (V.ref_count_ != NULL)
|
|
(*(V.ref_count_))++;
|
|
}
|
|
|
|
|
|
template <class T>
|
|
i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {}
|
|
|
|
template <class T>
|
|
inline T* i_refvec<T>::begin()
|
|
{
|
|
return data_;
|
|
}
|
|
|
|
template <class T>
|
|
inline const T& i_refvec<T>::operator[](int i) const
|
|
{
|
|
return data_[i];
|
|
}
|
|
|
|
template <class T>
|
|
inline T& i_refvec<T>::operator[](int i)
|
|
{
|
|
return data_[i];
|
|
}
|
|
|
|
|
|
template <class T>
|
|
inline const T* i_refvec<T>::begin() const
|
|
{
|
|
return data_;
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V)
|
|
{
|
|
if (this == &V)
|
|
return *this;
|
|
|
|
|
|
if (ref_count_ != NULL)
|
|
{
|
|
(*ref_count_) --;
|
|
if ((*ref_count_) == 0)
|
|
destroy();
|
|
}
|
|
|
|
data_ = V.data_;
|
|
ref_count_ = V.ref_count_;
|
|
|
|
if (V.ref_count_ != NULL)
|
|
(*(V.ref_count_))++;
|
|
|
|
return *this;
|
|
}
|
|
|
|
template <class T>
|
|
void i_refvec<T>::destroy()
|
|
{
|
|
if (ref_count_ != NULL)
|
|
{
|
|
#ifdef CGAL_TNT_DEBUG
|
|
std::cout << "destorying data... \n";
|
|
#endif
|
|
delete ref_count_;
|
|
|
|
#ifdef CGAL_TNT_DEBUG
|
|
std::cout << "deleted ref_count_ ...\n";
|
|
#endif
|
|
if (data_ != NULL)
|
|
delete []data_;
|
|
#ifdef CGAL_TNT_DEBUG
|
|
std::cout << "deleted data_[] ...\n";
|
|
#endif
|
|
data_ = NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* return 1 is vector is empty, 0 otherwise
|
|
*
|
|
* if is_null() is false and ref_count() is 0, then
|
|
*
|
|
*/
|
|
template<class T>
|
|
int i_refvec<T>::is_null() const
|
|
{
|
|
return (data_ == NULL ? 1 : 0);
|
|
}
|
|
|
|
/*
|
|
* returns -1 if data is external,
|
|
* returns 0 if a is NULL array,
|
|
* otherwise returns the positive number of vectors sharing
|
|
* this data space.
|
|
*/
|
|
template <class T>
|
|
int i_refvec<T>::ref_count() const
|
|
{
|
|
if (data_ == NULL)
|
|
return 0;
|
|
else
|
|
return (ref_count_ != NULL ? *ref_count_ : -1) ;
|
|
}
|
|
|
|
template <class T>
|
|
i_refvec<T>::~i_refvec()
|
|
{
|
|
if (ref_count_ != NULL)
|
|
{
|
|
(*ref_count_)--;
|
|
|
|
if (*ref_count_ == 0)
|
|
destroy();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
CGAL_TNT_END_NAMESPACE
|
|
|
|
#endif
|
|
/* TNT_I_REFVEC_H */
|
|
|