// LAPACK++ (V. 1.1)
// (C) 1992-1996 All Rights Reserved.
//
// Lapack++ "Shared" Vector Complex Class
//
// A lightweight vector class with minimal overhead.
//
// shallow assignment
// unit stride
// inlined access A(i)
// optional (compile-time) array bounds checking through
// VECTOR_COMPLEX_BOUNDS_CHECK
// A(i) is the same as A[i]
// auto conversion to complex*
// a null vector has size of 0, but has the ref_count structure
// has been initalized
//
#ifndef _VECTOR_COMPLEX_H_
#define _VECTOR_COMPLEX_H_
#include <iostream> // for formatted printing of matrices
#include "arch.h"
#include "lacomplex.h"
#ifndef __ASSERT_H
#include <cassert> // cheap "error" protection used in checking
#endif // checking array bounds.
#ifndef LA_COMPLEX_SUPPORT
/* An application must define LA_COMPLEX_SUPPORT if it wants to use
* complex numbers here. */
# error "The macro LA_COMPLEX_SUPPORT needs to be defined if you want to use complex-valued matrices."
#endif
typedef struct vrefComplex {
typedef COMPLEX value_type;
int sz;
value_type * data;
int ref_count;
int vref_ref_count;
vrefComplex(value_type *_data, int _sz)
: sz(_sz)
, data(_data)
, ref_count(2)
, vref_ref_count(1)
{};
vrefComplex(int _sz)
: sz(_sz)
, data(new value_type[sz])
, ref_count(1)
, vref_ref_count(1)
{};
} vrefComplex;
class DLLIMPORT VectorComplex
{
public:
/// The type of the values in this vector
typedef COMPLEX value_type;
private:
/// The type of the internal management structure
typedef vrefComplex vref_type;
vref_type *p;
value_type *data; // performance hack, avoid COMPLEX
// indirection to data.
/** Dereferences the vref management structure,
* deleting it if that was the last reference. */
inline void unref_vref();
/** Make this class a reference to the given vref
* management structure. Make sure to call unref_vref()
* beforehand, if suitable. */
inline void ref_vref(vref_type* other);
public:
/*::::::::::::::::::::::::::*/
/* Constructors/Destructors */
/*::::::::::::::::::::::::::*/
//inline VectorComplex(); // this should behave as VectorComplex(0)
VectorComplex(unsigned);
VectorComplex(unsigned, COMPLEX); // can't be inlined because of 'for'
// statement.
VectorComplex(COMPLEX*, unsigned);
VectorComplex(COMPLEX*, unsigned, unsigned, bool);
VectorComplex(const VectorComplex&);
~VectorComplex() ;
/*::::::::::::::::::::::::::::::::*/
/* Indices and access operations */
/*::::::::::::::::::::::::::::::::*/
inline COMPLEX& operator[](int);
inline COMPLEX& operator[](int) const; // read only
inline COMPLEX& operator()(int);
inline COMPLEX& operator()(int) const; // read only
inline operator COMPLEX*();
inline int size() const;
inline int null() const;
int resize(unsigned d);
inline int ref_count() const; // return the number of ref counts
inline COMPLEX* addr() const;
/*::::::::::::::*/
/* Assignment */
/*::::::::::::::*/
inline VectorComplex& operator=(const VectorComplex&);
VectorComplex& operator=(COMPLEX);
inline VectorComplex& ref(const VectorComplex &);
VectorComplex& inject(const VectorComplex&);
VectorComplex& copy(const VectorComplex&);
/* I/O */
friend std::ostream& operator<<(std::ostream&, const VectorComplex&);
};
// operators and member functions
inline int VectorComplex::null() const
{
return (size() == 0) ;
}
inline int VectorComplex::size() const
{
return p-> sz;
}
inline int VectorComplex::ref_count() const
{
return p->ref_count;
}
inline COMPLEX* VectorComplex::addr() const
{
return data;
}
inline VectorComplex::operator COMPLEX*()
{
return data;
}
inline COMPLEX& VectorComplex::operator()(int i)
{
#ifdef VECTOR_COMPLEX_BOUNDS_CHECK
assert(0<=i && i<size());
#endif
return data[i];
}
inline COMPLEX& VectorComplex::operator()(int i) const
{
#ifdef VECTOR_COMPLEX_BOUNDS_CHECK
assert(0<=i && i<size());
#endif
return data[i];
}
// [] *always* performs bounds-check
// *CHANGE* [] is the same as ()
inline COMPLEX& VectorComplex::operator[](int i)
{
#ifdef VECTOR_COMPLEX_BOUNDS_CHECK
assert(0<=i && i<size());
#endif
return data[i];
}
// [] *always* performs bounds-check
// *CHANGE* [] is the same as ()
inline COMPLEX& VectorComplex::operator[](int i) const
{
#ifdef VECTOR_COMPLEX_BOUNDS_CHECK
assert(0<=i && i<size());
#endif
return data[i];
}
inline void VectorComplex::ref_vref(vref_type* other)
{
p = other;
data = p->data;
p->ref_count++;
p->vref_ref_count++;
}
inline void VectorComplex::unref_vref()
{
if (--(p->ref_count) == 0) // perform garbage col.
{
delete [] p->data;
delete p;
}
else
{
// Check whether the internal management structure needs to
// be deleted
if (--(p->vref_ref_count) == 0)
delete p;
}
}
inline VectorComplex& VectorComplex::ref(const VectorComplex& m)
{
if (&m != this)
{
unref_vref();
ref_vref(m.p);
}
return *this;
}
inline VectorComplex& VectorComplex::operator=(const VectorComplex& m)
{
return ref(m);
}
#ifndef LA_COMPLEX_SUPPORT
// Repeat this warning again
# error "The macro LA_COMPLEX_SUPPORT needs to be defined if you want to use complex-valued matrices."
#endif
#endif
// _VECTOR_COMPLEX_H_
syntax highlighted by Code2HTML, v. 0.9.1