home *** CD-ROM | disk | FTP | other *** search
- /*
- * Definitions for <T>Vec
- *
- * Copyright (C) 1988, 1989.
- *
- * Dr. Thomas Keffer
- * Rogue Wave Associates
- * P.O. Box 85341
- * Seattle WA 98145-1341
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and
- * without fee is hereby granted, provided that the
- * above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice
- * appear in supporting documentation.
- *
- * This software is provided "as is" without any
- * expressed or implied warranty.
- *
- *
- * @(#)xvec.cc 2.1 8/18/89
- */
-
- #define NO_VECTOR_MATHFUN
- #include "rw/<T>Vec.h"
- #define TYPE <T>_TYPE
- #include "vecdefs.h"
-
- #if TYPE==DComplex_TYPE
- #include "rw/<P>Vec.h"
- #endif
-
- #if NEEDS_OVERLOAD
- overload <T>Copy;
- #endif
-
- inline void
- <T>Copy(register const <T>* src, register <T>* dst, register int n)
- // Copy n <T> elements from src to dst with stride of 1
- {
- while (n--) *dst++ = *src++;
- }
-
- inline void
- <T>Copy(register const <T>* src, register int str,
- register <T>* dst, register int n)
- // Copy n <T> elements from src to dst with stride str
- {
- while (n--){
- *dst++ = *src; src += str;
- }
- }
-
- inline void
- <T>Copy(register const <T>* src, register int srcstr,
- register <T>* dst, register int dststr, register int n)
- {
- while (n--){
- *dst = *src; src += srcstr; dst += dststr;
- }
- }
-
- <T>Vec::<T>Vec()
- {
- block = new <T>Block(0);
- npts = 0;
- step = 1;
- begin = block->data();
- }
-
- <T>Vec::<T>Vec(unsigned n)
- {
- block = new <T>Block(n);
- npts = n;
- step = 1;
- begin = block->data();
- }
-
- <T>Vec::<T>Vec(unsigned n, <T> val)
- {
- block = new <T>Block(n, val);
- npts = n;
- step = 1;
- begin = block->data();
- }
-
- <T>Vec::<T>Vec(unsigned n, <T> val, <T> by)
- {
- block = new <T>Block(n, val, by);
- npts = n;
- step = 1;
- begin = block->data();
- }
-
- #if TYPE==DComplex_TYPE || TYPE==FComplex_TYPE
- <T>Vec::<T>Vec(const <P>Vec& re)
- {
- register int nn = npts = re.length();
- block = new <T>Block(nn);
- step = 1;
- register <T>* cp = begin = block->data();
- register <P>* rp = re.data();
- register int rstride = re.stride();
- while(nn--){ *cp++ = <T>(*rp); rp += rstride; }
- }
-
- <T>Vec::<T>Vec(const <P>Vec& re, const <P>Vec& im)
- {
- register int nn = npts = re.length();
- lengthCheck(im.length());
- block = new <T>Block(nn);
- step = 1;
- register <T>* cp = begin = block->data();
- register <P>* rp = re.data();
- register <P>* ip = im.data();
- register int rstride = re.stride();
- register int istride = im.stride();
- while(nn--){
- *cp++ = <T>(*rp, *ip);
- rp += rstride;
- ip += istride;
- }
- }
-
- #endif
-
- <T>Vec::<T>Vec(const <T>Vec& a)
- {
- block = a.block;
- block->add_reference();
- npts = a.npts;
- begin = a.begin;
- step = a.step;
- }
-
- <T>Vec::<T>Vec(const <T>* dat, unsigned n)
- {
- npts = n;
- block = new <T>Block(n);
- step = 1;
- <T>Copy(dat, begin = block->data(), n);
- }
-
- <T>Vec::<T>Vec(<T>Vec& v, int start, unsigned n, int str)
- {
- int maxv = v.length()-1; // Last subscript in v
- int maxslice = start + (n-1)*str; // Last subscript in slice
- if(start<0 || start>maxv || maxslice<0 || maxslice>maxv)
- sliceErr(v.length(), start, n, str);
-
- block = v.block;
- block->add_reference();
- begin = v.begin + start*v.step;
- npts = n;
- step = str*v.step;
- }
-
- <T>Vec::~<T>Vec()
- {
- delete block;
- }
-
- <T>Vec
- <T>Vec::slice(int start, unsigned n, int str)
- {
- <T>Vec temp(*this, start, n, str);
- return temp;
- }
-
- <T>Vec&
- <T>Vec::operator=(const <T>Vec& a)
- {
- lengthCheck(a.length());
- <T>Copy(a.begin, a.step, begin, step, npts);
- return *this;
- }
-
-
- <T>Vec&
- <T>Vec::operator=(<T> d)
- {
- register int n = length();
- register <T>* tp = data();
- register int tj = stride();
- REGISTER <T> dd = d;
- while(n--){
- *tp = dd; tp += tj;
- }
- return *this;
- }
-
- <T>Vec&
- <T>Vec::reference(<T>Vec& v)
- {
- delete block; // Detach from old block
- block = v.block; // Attach new block
- block->add_reference();
- npts = v.npts;
- step = v.step;
- begin = v.begin;
- return *this;
- }
-
- // Return copy of self with distinct instance variables
- <T>Vec
- <T>Vec::deepCopy()
- {
- <T>Vec temp(npts);
- <T>Copy(begin, step, temp.data(), npts);
- return temp;
- }
-
- // Guarantee that references==1 and stride==1
- void
- <T>Vec::deepenShallowCopy()
- {
- if(block->references() > 1 || stride() != 1 || begin != block->data() ){
- <T>Block* newblock = new <T>Block(npts);
- <T>Copy(begin, step, newblock->data(), npts);
- delete block; // Detach old block
- block = newblock;
- step = 1;
- begin = block->data();
- }
- }
-
- void
- <T>Vec::resize(unsigned N)
- {
- if(N != npts){
- <T>Block* newblock = new <T>Block(N);
- // Copy over old stuff.
- int newLength = min( int(npts), int(N) );
- <T>Copy(begin, step, newblock->data(), newLength );
- delete block; // Disconnect from old block
- block = newblock;
- step = 1;
- begin = block->data();
- // If vector has grown, zero out the extra storage
- unsigned hold = npts;
- npts = N;
- if(hold<N)slice(hold, N-hold, 1) = <T>(0);
- }
- }
-