This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

problems with solaris version


Hello,

I'm hoping you can help me with this.

I have tried using the valarray standard template library... well, it's
not in the currently released library yet but is supposed to be at some
point.  I've tried using it and it works fine using egcs (latest
release) on Linux but craps out on egcs on Solaris, notably when I use
the iostreams.  The pertinent files are attached.   I would appreciate
very much knowing what you find out and any advice on workarounds.

Many thanks.

Michael L. Shire
shire@icsi.berkeley.edu

===============
compile command:  gcc -v -g -o test test.C
execution command: ./test

example output on Solaris:

length=10
past n+=2
Segmentation fault

example output on Linux:

length=10
past n+=2
0 3
1 3
2 3
3 3
4 3
5 3
6 3
7 3
8 3
9 3
max=3
min=3
#include <iostream.h>
#include <complex.h>
#include <stdlib.h>
#include <math.h>
#include "valarray.h"


using namespace std;
int main(){
  valarray<float> n(1,10);
  n += 2.0;
  cout << "length=" << n.length() << "\n";
  cout << "past n+=2\n";
  for(int i=0; i<n.length();i++){
	cout << i << " " << n[i] << "\n";
  }
  cout << "max=" <<n.max() <<"\n";
  cout << "min=" <<n.min() <<"\n";
  return (0);
}
// Copyright (C) 1994 Free Software Foundation

// This file is part of the GNU ANSI C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// 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, 59 Temple Place-Suite 330, Boston, MA  02111-1307, USA.

// As a special exception, if you link this library with files
// compiled with a GNU compiler to produce an executable, this does not 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.

// Written by Robert D. Pierce based upon the specification in the 28 April 1995
// C++ working paper, ANSI document X3J16/95-0087

#ifndef _valarray_h_
#define _valarray_h_

#include<stddef.h>
#include<math.h>

class slice;
class gslice;
template<class T> class slice_array;
template<class T> class gslice_array;
template<class T> class indirect_array;
template<class T> class mask_array;


template<class T> 
class valarray 
{
public:
  // Constructors
  valarray();
  valarray(size_t dim);
  valarray(const T& a,size_t dim);
  valarray(const T* a,size_t dim);
  valarray(const valarray& a);
  valarray(const slice_array<T>& a);
  valarray(const gslice_array<T>& a);
  valarray(const mask_array<T>& a);
  valarray(const indirect_array<T>& a);
  ~valarray();

  // Element access, 0-offset access
  T& operator[](size_t c);
  T operator[](size_t c) const;

  // Subset
  valarray operator[](slice) const;
  slice_array<T> operator[](slice);
  valarray operator[](const gslice) const;
  gslice_array<T> operator[](const gslice);
  valarray operator[](const valarray<bool>&) const;
  mask_array<T> operator[](const valarray<bool>&);
  valarray operator[](const valarray<size_t>&) const;
  indirect_array<T> operator[](const valarray<size_t>&);

  // Shifting:
  valarray shift(int n) const;
  valarray cshift(int n) const;

  // Threading operations
  void fill(const T &a);
  void fill(const T* a);

  // Sup and inf norm
  T max() const;
  T min() const;
  T sum() const;
  valarray apply(T (*f)(T)) const;
  valarray apply(T (*f)(const T&)) const;
  size_t length() const;
  operator T*();
  operator const T*() const;
  void free();
  valarray& operator=(const valarray &a);
  valarray& operator=(const slice_array<T> &a);
  valarray& operator=(const gslice_array<T> &a);
  valarray& operator=(const mask_array<T> &a);
  valarray& operator=(const indirect_array<T> &a);

  valarray& operator+=(const T& a);
  valarray& operator-=(const T& a);
  valarray& operator*=(const T& a);
  valarray& operator/=(const T& a);
  valarray& operator%=(const T& a);
  valarray& operator^=(const T& a);
  valarray& operator&=(const T& a);
  valarray& operator|=(const T& a);
  valarray& operator<<=(const T& a);
  valarray& operator>>=(const T& a);

  valarray& operator+=(const valarray& a);
  valarray& operator-=(const valarray& a);
  valarray& operator*=(const valarray& a);
  valarray& operator/=(const valarray& a);
  valarray& operator%=(const valarray& a);
  valarray& operator^=(const valarray& a);
  valarray& operator&=(const valarray& a);
  valarray& operator|=(const valarray& a);
  valarray& operator<<=(const valarray& a);
  valarray& operator>>=(const valarray& a);

  valarray operator+();
  valarray operator-();
  valarray operator~();
  valarray operator!();

private:
  T* data;                // pointer to first element
  size_t dimen;           // # of elements
  void alloc(size_t d);
};        // End of class valarray


// DECLARATIONS OF SLICE CLASSES

class slice 
{
public:
  slice();
  slice(size_t o,size_t d,size_t s);
  size_t start() const;
  size_t length() const;
  size_t stride() const;
private:
  size_t offset,dimen,skip;
};

class gslice 
{
public:
  gslice();
  gslice(size_t o,const valarray<size_t> &d,const valarray<size_t> &s);
  size_t start() const;
  valarray<size_t> length() const;
  valarray<size_t> stride() const;
private:
  size_t offset;
  valarray<size_t> dimen,skip;
};


template<class T> 
class slice_array 
{
public:
  ~slice_array();
  void fill(const T &a);
  void operator=(const valarray<T> &a) const;
  void operator+=(const valarray<T>& a) const;
  void operator-=(const valarray<T>& a) const;
  void operator*=(const valarray<T>& a) const;
  void operator/=(const valarray<T>& a) const;
  void operator%=(const valarray<T>& a) const;
  void operator^=(const valarray<T>& a) const;
  void operator&=(const valarray<T>& a) const;
  void operator|=(const valarray<T>& a) const;
  void operator<<=(const valarray<T>& a) const;
  void operator>>=(const valarray<T>& a) const;
protected:
  friend class valarray<T>;
  T* data;
  size_t dimen;
  size_t skip;

  size_t length() const;
  T& operator[](size_t j) const;
  slice_array();
  slice_array(const slice_array& a);
  slice_array& operator=(const slice_array &a);
  slice_array(T* a,const slice &sl);
};


template<class T> 
class indirect_array 
{
public:
  ~indirect_array();
  void fill(const T &a);
  void operator=(const valarray<T> &a) const;
  void operator+=(const valarray<T>& a) const;
  void operator-=(const valarray<T>& a) const;
  void operator*=(const valarray<T>& a) const;
  void operator/=(const valarray<T>& a) const;
  void operator%=(const valarray<T>& a) const;
  void operator^=(const valarray<T>& a) const;
  void operator&=(const valarray<T>& a) const;
  void operator|=(const valarray<T>& a) const;
  void operator<<=(const valarray<T>& a) const;
  void operator>>=(const valarray<T>& a) const;
protected:
  friend class valarray<T>;
  T* data;
  valarray<size_t> s;

  size_t length() const;
  T& operator[](size_t j) const;
  indirect_array();
  indirect_array(const indirect_array& a);
  indirect_array& operator=(const indirect_array &a);
  indirect_array(T* a,const valarray<size_t> &sl);
  indirect_array(T* a,const gslice &sl);
  indirect_array(T* a,const valarray<bool> &sl);
};

template<class T> 
class gslice_array : public indirect_array<T> 
{
public:
  ~gslice_array();
protected:
  friend class valarray<T>;
  gslice_array();
  gslice_array(const gslice_array& a);
  gslice_array& operator=(const gslice_array &a);
  gslice_array(T* a,const gslice &sl);
};


template<class T> 
class mask_array : public indirect_array<T> 
{
public:
  ~mask_array();
protected:
  friend class valarray<T>;
  mask_array();
  mask_array(const mask_array& a);
  mask_array& operator=(const mask_array &a);
  mask_array(T* a,const valarray<bool> &sl);
};


// DEFINITION OF VALARRAY FUNCTIONS

template<class T>
valarray<T>::valarray() : data(0), dimen(0) {}

template<class T>
valarray<T>::valarray(size_t dim) : data(0) { alloc(dim); }

template<class T>
valarray<T>::valarray(const T& a,size_t dim) : data(0) { alloc(dim); fill(a); }

template<class T>
valarray<T>::valarray(const T* a,size_t dim) : data(0) { alloc(dim); fill(a); }

template<class T>
valarray<T>::valarray(const valarray<T>& a) : data(0) { (*this)=a; }

template<class T>
valarray<T>::valarray(const slice_array<T>& a) : data(0) { (*this)=a; }

template<class T>
valarray<T>::valarray(const gslice_array<T>& a) : data(0) { (*this)=a; }

template<class T>
valarray<T>::valarray(const mask_array<T>& a) : data(0) { (*this)=a; }

template<class T>
valarray<T>::valarray(const indirect_array<T>& a) : data(0) { (*this)=a; }

template<class T>
valarray<T>::~valarray() { free(); }

// Element access, 0-offset access

template<class T>
T& 
valarray<T>::operator[](size_t c) { return data[c]; }

template<class T>
T 
valarray<T>::operator[](size_t c) const { return data[c]; }

// Threading operations

template<class T>
void 
valarray<T>::fill(const T &a) { for(size_t j=0;j<=length();j++) (*this)[j]=a; }

template<class T>
void 
valarray<T>::fill(const T* a) { for(size_t j=0;j<=length();j++) (*this)[j]=a[j]; }

// Sup and inf norm

template<class T>
T 
valarray<T>::max() const 
{
  size_t j=0;
  T m=(*this)[j];
  for(j++;j < length();j++) {
    if(m<(*this)[j]) m=(*this)[j];
  }
  return m; 
}

template<class T>
T 
valarray<T>::min() const 
{
  size_t j=0;
  T m=(*this)[j];
  for(j++;j < length();j++) {
    if(m>(*this)[j]) m=(*this)[j];
  }
  return m; 
}

template<class T>
T 
valarray<T>::sum() const 
{
  size_t j=0;
  T t=(*this)[j];
  for(j++;j < length();j++) t+=(*this)[j];
  return t; 
}

// applies f() to each element
template<class T>
valarray<T> 
valarray<T>::apply(T (*f)(T)) const 
{ 
  valarray<T> a(length());
  for(size_t j=0;j<=length();j++) a[j]=f((*this)[j]); 
  return a; 
}

template<class T>
valarray<T> 
valarray<T>::apply(T (*f)(const T&)) const 
{
  valarray<T> a(length());
  for(size_t j=0;j<=length();j++) a[j]=f((*this)[j]); 
  return a; 
}

// Memory
template<class T>
size_t 
valarray<T>::length() const { return dimen; }    // # of valid elements

template<class T>
valarray<T>::operator T*() { return data; }   // pointer to first valid element

template<class T>
valarray<T>::operator const T*() const { return data; }

template<class T>
void 
valarray<T>::free() 
{                   // deallocate memory
  if(data==0) delete [] data;
  data=0;
  dimen=0; 
}

// Assignment operations
template<class T>
valarray<T>& 
valarray<T>::operator=(const valarray<T> &a) 
{  // op= reallocates the array
  free();
  alloc(a.length());
  for(size_t j=0;j<length();j++) (*this)[j]=a[j];
  return (*this); 
}

template<class T>
void 
valarray<T>::alloc(size_t d) 
{                // allocate memory
  if(data!=0) free();
  data=new T[d];
  dimen=d; 
}

template<class T> 
valarray<T> 
valarray<T>::operator[](slice s) const 
{
  return valarray<T>(slice_array<T>(data,s));
}

template<class T> 
slice_array<T> 
valarray<T>::operator[](slice s) 
{
  return slice_array<T>(data,s);
}

template<class T> 
valarray<T> 
valarray<T>::operator[](const gslice s) const 
{
  return valarray<T>(gslice_array<T>(data,s));
}

template<class T> 
gslice_array<T> 
valarray<T>::operator[](const gslice s) 
{
  return gslice_array<T>(data,s);
}

template<class T> 
valarray<T> 
valarray<T>::operator[](const valarray<bool>& s) const 
{
  return valarray<T>(mask_array<T>(data,s));
}

template<class T> 
mask_array<T> 
valarray<T>::operator[](const valarray<bool>& s) 
{ 
  return mask_array<T>(data,s);
}

template<class T> 
valarray<T> 
valarray<T>::operator[](const valarray<size_t>& s) const 
{ 
  return valarray<T>(indirect_array<T>(data,s));
}

template<class T> 
indirect_array<T> 
valarray<T>::operator[](const valarray<size_t>& s) 
{ 
  return indirect_array<T>(data,s);
}

template<class T> 
T 
max(const valarray<T>& a) { return a.max(); }

template<class T> 
T 
min(const valarray<T>& a) { return a.min(); }

template<class T> 
valarray<T>
valarray<T>::shift(int n) const
{
// Shifts the array by n indeces, filling vacated spots with default values.  
// Whether this is "right" or "left" depends on how you order the indeces.
  const valarray<T> &a=(*this);
  valarray<T> result(length());
  int l=a.length();
  n%=l;
  if(n==0) {
    for(size_t j=0;j < l;j++) result[j]=a[j]; // copy
    return result;   // return the identity
  }
  T t,tp=a[0];    // next and previous elements
  int i,ip=1;                // next and previous indeces
  for(size_t j=1;j<=l;j++) {    // l swaps
    i=(ip+n)%l;              // next element to swap
    if(i<=0) i+=l;           // reflect back onto the index range
    ip=i-1;
    t=a[ip];               // store current element
    if(ip < n) result[ip]=T();   // check if it is to be zeroed.
    else if(ip >= a.length()+n) result[ip]=T();
    else result[ip]=tp;              // replace with previous element
    tp=t;                    // set up for next swap
    ip=i;
  }
  return result;
}

template<class T> 
valarray<T>
valarray<T>::cshift(int n) const
{
// Cyclically shifts the array by n indeces.
  const valarray<T> &a=(*this);
  valarray<T> result(length());
  int l=a.length();
  n%=l;
  if(n==0) {
    for(size_t j=0;j < l;j++) result[j]=a[j]; // copy
    return result;   // return the identity
  }
  T t,tp=a[0];  // next and previous elements
  int i,ip=1;                // next and previous indeces
  for(size_t j=1;j<=l;j++) {    // l swaps
    i=(ip+n)%l;              // next element to swap
    if(i<=0) i+=l;           // reflect back onto the index range
    ip=i-1;
    t=a[ip];                 // store current element
    result[ip]=tp;           // replace with previous element
    tp=t;                    // set up for next swap
    ip=i;
  }
  return result;
}

// Assignmnent

template<class T> 
valarray<T>& 
valarray<T>::operator=(const slice_array<T> &a) 
{ 
  free();
  alloc(a.length());
  for(size_t j=0;j<length();j++) (*this)[j]=a[j];
  return (*this); 
}

template<class T> 
valarray<T>& 
valarray<T>::operator=(const indirect_array<T> &a) 
{
  free();
  alloc(a.length());
  for(size_t j=0;j<length();j++) (*this)[j]=a[j];
  return (*this); 
}

template<class T> 
valarray<T>& 
valarray<T>::operator=(const gslice_array<T> &a) 
{
  free();
  alloc(a.length());
  for(size_t j=0;j<length();j++) (*this)[j]=a[j];
  return (*this); 
}

template<class T> 
valarray<T>& 
valarray<T>::operator=(const mask_array<T> &a) 
{
  free();
  alloc(a.length());
  for(size_t j=0;j<length();j++) (*this)[j]=a[j];
  return (*this); 
}


// MACRO DEFINITIONS


#define binary(_SYMBOL_)						\
									\
template<class T> 							\
valarray <T>& 								\
valarray<T>::operator _SYMBOL_ ## =(const T& b)				\
{									\
  for(size_t j= 0 ;j < length();j++) (*this)[j] _SYMBOL_ ## = b;	\
  return (*this);							\
}									\
									\
template<class T> 							\
valarray <T>& 								\
valarray<T>::operator _SYMBOL_ ## =(const  valarray<T>& b) 		\
{									\
  for(size_t j= 0 ;j < length();j++) (*this)[j] _SYMBOL_ ## = b[j];	\
  return (*this);							\
}									\
									\
template<class T>						 	\
valarray <T>								\
operator _SYMBOL_(const valarray<T>& a,const  valarray<T>& b)		\
{									\
  valarray<T> c(a.length());						\
  for(size_t j= 0 ;j < a.length();j++) c[j]=a[j] _SYMBOL_ b[j];		\
  return c;								\
}									\
									\
template<class T>						 	\
valarray <T>								\
operator _SYMBOL_(const valarray<T>& a,const T& b)			\
{									\
  valarray<T> c(a.length());						\
  for(size_t j= 0 ;j < a.length();j++) c[j]=a[j] _SYMBOL_ b;		\
  return c;								\
}									\
									\
template<class T>						 	\
valarray <T>								\
operator _SYMBOL_(const T& a,const  valarray<T>& b)			\
{									\
  valarray<T> c(b.length());						\
  for(size_t j= 0 ;j < b.length();j++) c[j]=a _SYMBOL_ b[j];		\
  return c;								\
}


#define unary(_SYMBOL_) 						\
									\
template<class T> 							\
valarray<T>								\
valarray<T>::operator _SYMBOL_() 					\
{									\
  valarray<T> a(length());						\
  for(size_t j=0;j<length();j++) a[j]= _SYMBOL_ (*this)[j];		\
  return a;								\
}


#define comp(_SYMBOL_)							\
									\
template<class T> 							\
valarray <bool>								\
operator _SYMBOL_(const valarray<T>& a,const  valarray<T>& b)		\
{									\
  valarray<bool> c(a.length());						\
  for(size_t j= 0 ;j < a.length();j++) c[j]=a[j] _SYMBOL_ b[j];		\
  return c;								\
}


#define math_unary(_SYMBOL_)						\
									\
template<class T> 							\
valarray<T>								\
_SYMBOL_(const valarray<T>& a) 						\
{									\
  valarray<T> b(a.length());						\
  for(size_t j=0;j<a.length();j++) b[j]= _SYMBOL_(a[j]);		\
  return b;								\
}


#define math_binary(_SYMBOL_)						\
									\
template<class T> 							\
valarray<T>								\
_SYMBOL_(const valarray<T>& a,const valarray<T>& b) 			\
{									\
  valarray<T> c(a.length());						\
  for(size_t j=0;j<a.length();j++) c[j]= _SYMBOL_(a[j],b[j]);		\
  return c;								\
}									\
									\
template<class T> 							\
valarray<T>								\
_SYMBOL_(const valarray<T>& a,const T& b) 				\
{									\
  valarray<T> c(a.length());						\
  for(size_t j=0;j<a.length();j++) c[j]= _SYMBOL_(a[j],b);		\
  return c;								\
}									\
									\
template<class T> 							\
valarray<T>								\
_SYMBOL_(const T& a,const valarray<T>& b) 				\
{									\
  valarray<T> c(b.length());						\
  for(size_t j=0;j<b.length();j++) c[j]= _SYMBOL_(a,b[j]);		\
  return c;								\
}

// MACRO EXPANSIONS

binary(+)
binary(-)
binary(*)
binary(/)
binary(%)
binary(^)
binary(&)
binary(|)
binary(<<)
binary(>>)
#undef binary

unary(+)
unary(-)
unary(~)
unary(!)
#undef unary

comp(==)
comp(!=)
comp(<=)
comp(>=)
comp(<)
comp(>)
#undef comp

math_unary(abs)
math_unary(sqrt)
math_unary(cos)
math_unary(sin)
math_unary(tan)
math_unary(acos)
math_unary(asin)
math_unary(atan)
math_unary(cosh)
math_unary(sinh)
math_unary(tanh)
math_unary(log)
math_unary(log10)
#undef math_unary

math_binary(pow)
math_binary(atan2)
#undef math_binary



// DEFINITIONS OF SLICE CLASS FUNCTIONS

slice::slice() : offset(0), dimen(0), skip(1) {}

slice::slice(size_t o,size_t d,size_t s) : offset(o), dimen(d), skip(s) {}

size_t slice::start() const { return offset; }

size_t slice::length() const { return dimen; }

size_t slice::stride() const { return skip; }

gslice::gslice() : offset(0) {}

gslice::gslice(size_t o,const valarray<size_t> &d,const valarray<size_t> &s) : 
offset(o), dimen(d), skip(s) {}

size_t gslice::start() const { return offset; }

valarray<size_t> gslice::length() const { return dimen; }

valarray<size_t> gslice::stride() const { return skip; }

template<class T>
slice_array<T>::~slice_array() {}

template<class T>
void 
slice_array<T>::fill(const T &a) 
{ 
  for(size_t j=0;j<length();j++) (*this)[j]=a; 
}

template<class T>
void 
slice_array<T>::operator=(const valarray<T> &a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] = a[j]; 
}

template<class T>
void 
slice_array<T>::operator+=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] += a[j]; 
}

template<class T>
void 
slice_array<T>::operator-=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] -= a[j]; 
}

template<class T>
void 
slice_array<T>::operator*=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] *= a[j]; 
}

template<class T>
void 
slice_array<T>::operator/=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] /= a[j]; 
}

template<class T>
void 
slice_array<T>::operator%=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] %= a[j]; 
}

template<class T>
void 
slice_array<T>::operator^=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] ^= a[j]; 
}

template<class T>
void 
slice_array<T>::operator&=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] &= a[j]; 
}

template<class T>
void 
slice_array<T>::operator|=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] |= a[j]; 
}

template<class T>
void 
slice_array<T>::operator<<=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] <<= a[j]; 
}

template<class T>
void 
slice_array<T>::operator>>=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] >>= a[j]; 
}

template<class T>
size_t 
slice_array<T>::length() const { return dimen; }
  // the const here is quite incorrect since a reference is returned,
  // but it is effectively mandated by the const on the assignments above

template<class T>
T& 
slice_array<T>::operator[](size_t j) const { return *(data+j*skip); }

template<class T>
slice_array<T>::slice_array(T* a,const slice &sl) : 
data(a+sl.start()), dimen(sl.length()), skip(sl.stride()) {}

template<class T>
indirect_array<T>::~indirect_array() {}

template<class T>
void 
indirect_array<T>::fill(const T &a) 
{ 
  for(size_t j=0;j<length();j++) (*this)[j]=a; 
}

template<class T>
void 
indirect_array<T>::operator=(const valarray<T> &a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] = a[j]; 
}

template<class T>
void 
indirect_array<T>::operator+=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] += a[j]; 
}

template<class T>
void 
indirect_array<T>::operator-=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] -= a[j]; 
}

template<class T>
void 
indirect_array<T>::operator*=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] *= a[j]; 
}

template<class T>
void 
indirect_array<T>::operator/=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] /= a[j]; 
}

template<class T>
void 
indirect_array<T>::operator%=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] %= a[j]; 
}

template<class T>
void 
indirect_array<T>::operator^=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] ^= a[j]; 
}

template<class T>
void 
indirect_array<T>::operator&=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] &= a[j]; 
}

template<class T>
void 
indirect_array<T>::operator|=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] |= a[j]; 
}

template<class T>
void 
indirect_array<T>::operator<<=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] <<= a[j]; 
}

template<class T>
void 
indirect_array<T>::operator>>=(const valarray<T>& a) const 
{
  for(size_t j= 0 ;j < length();j++) (*this)[j] >>= a[j]; 
}

template<class T>
size_t 
indirect_array<T>::length() const { return s.length(); }

template<class T>
T& 
indirect_array<T>::operator[](size_t j) const { return *(data+s[j]); }

template<class T>
indirect_array<T>::indirect_array(T* a,const valarray<size_t> &sl) : data(a), s(sl) {}

template<class T>
indirect_array<T>::indirect_array(T* a,const gslice &sl) : data(a+sl.start()) 
{
  int d=sl.length().length();  // number of indices
  int n=1;
  for(size_t j=0;j<d;j++) n*=sl.length()[j];   // number of elements
  s=valarray<size_t>(n);       // allocate the indirection array
  valarray<size_t> v(d);       // array to loop over indeces
  s.fill((size_t)0);
  v.fill((size_t)0);
  for(size_t j=0;j<n;j++) {
    s[j]=0;
    for(size_t k=0;k<d;k++) s[j]+=v[k]*sl.stride()[k];
    v[d-1]++;
    for(size_t l=d-1;l>0;l--) {
      if(v[l]>=sl.length()[l]) {
        v[l]=0;
        v[l-1]++;
      } else break; } } 
}

template<class T>
indirect_array<T>::indirect_array(T* a,const valarray<bool> &sl) : data(a) 
{
  size_t j,n;
  for(j=n=0;j<sl.length();j++) if(sl[j]) n++;   // number of elements
  valarray<size_t> st(n);
  for(j=n=0;j<sl.length();j++) if(sl[j]) st[n++]=j;
  s=st; 
}


template<class T>
gslice_array<T>::~gslice_array() {}

template<class T>
gslice_array<T>::gslice_array(T* a,const gslice &sl) : indirect_array<T>(a,sl) {}


template<class T>
mask_array<T>::~mask_array() {}

template<class T>
mask_array<T>::mask_array(T* a,const valarray<bool> &sl) : indirect_array<T>(a,sl) {}

#endif       _valarray_h_


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]