`/* Implementation of the RESHAPE
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002, 2006 Free Software Foundation, Inc.
Contributed by Paul Brook <paul@nowt.org>
This file is part of the GNU Fortran 95 runtime library (libgfortran).
You should have received a copy of the GNU General Public
License along with libgfortran; see the file COPYING. If not,
-write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include "config.h"
#include <stdlib.h>
#include "libgfortran.h"'
include(iparm.m4)dnl
+`#if defined (HAVE_'rtype_name`)'
+
typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
-/* The shape parameter is ignored. We can currently deduce the shape from the
- return array. */
-dnl Only the kind (ie size) is used to name the function.
+dnl For integer routines, only the kind (ie size) is used to name the
+dnl function. The same function will be used for integer and logical
+dnl arrays of the same kind.
-extern void reshape_`'rtype_kind (rtype *, rtype *, shape_type *,
- rtype *, shape_type *);
-export_proto(reshape_`'rtype_kind);
+extern void reshape_`'rtype_ccode (rtype * const restrict,
+ rtype * const restrict,
+ shape_type * const restrict,
+ rtype * const restrict,
+ shape_type * const restrict);
+export_proto(reshape_`'rtype_ccode);
void
-reshape_`'rtype_kind (rtype * ret, rtype * source, shape_type * shape,
- rtype * pad, shape_type * order)
+reshape_`'rtype_ccode (rtype * const restrict ret,
+ rtype * const restrict source,
+ shape_type * const restrict shape,
+ rtype * const restrict pad,
+ shape_type * const restrict order)
{
/* r.* indicates the return array. */
index_type rcount[GFC_MAX_DIMENSIONS];
const rtype_name *src;
int n;
int dim;
-
- if (source->dim[0].stride == 0)
- source->dim[0].stride = 1;
- if (shape->dim[0].stride == 0)
- shape->dim[0].stride = 1;
- if (pad && pad->dim[0].stride == 0)
- pad->dim[0].stride = 1;
- if (order && order->dim[0].stride == 0)
- order->dim[0].stride = 1;
+ int sempty, pempty;
if (ret->data == NULL)
{
rdim = shape->dim[0].ubound - shape->dim[0].lbound + 1;
rs = 1;
- for (n=0; n < rdim; n++)
+ for (n = 0; n < rdim; n++)
{
ret->dim[n].lbound = 0;
rex = shape->data[n * shape->dim[0].stride];
ret->dim[n].stride = rs;
rs *= rex;
}
- ret->base = 0;
+ ret->offset = 0;
ret->data = internal_malloc_size ( rs * sizeof (rtype_name));
ret->dtype = (source->dtype & ~GFC_DTYPE_RANK_MASK) | rdim;
}
else
{
rdim = GFC_DESCRIPTOR_RANK (ret);
- if (ret->dim[0].stride == 0)
- ret->dim[0].stride = 1;
}
rsize = 1;
sdim = GFC_DESCRIPTOR_RANK (source);
ssize = 1;
+ sempty = 0;
for (n = 0; n < sdim; n++)
{
scount[n] = 0;
sstride[n] = source->dim[n].stride;
sextent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
if (sextent[n] <= 0)
- abort ();
+ {
+ sempty = 1;
+ sextent[n] = 0;
+ }
if (ssize == sstride[n])
ssize *= sextent[n];
{
pdim = GFC_DESCRIPTOR_RANK (pad);
psize = 1;
+ pempty = 0;
for (n = 0; n < pdim; n++)
{
pcount[n] = 0;
pstride[n] = pad->dim[n].stride;
pextent[n] = pad->dim[n].ubound + 1 - pad->dim[n].lbound;
if (pextent[n] <= 0)
- abort ();
+ {
+ pempty = 1;
+ pextent[n] = 0;
+ }
+
if (psize == pstride[n])
psize *= pextent[n];
else
{
pdim = 0;
psize = 1;
+ pempty = 1;
pptr = NULL;
}
if (rsize != 0 && ssize != 0 && psize != 0)
{
- rsize *= rtype_kind;
- ssize *= rtype_kind;
- psize *= rtype_kind;
+ rsize *= sizeof (rtype_name);
+ ssize *= sizeof (rtype_name);
+ psize *= sizeof (rtype_name);
reshape_packed ((char *)ret->data, rsize, (char *)source->data,
ssize, pad ? (char *)pad->data : NULL, psize);
return;
rstride0 = rstride[0];
sstride0 = sstride[0];
+ if (sempty && pempty)
+ abort ();
+
+ if (sempty)
+ {
+ /* Switch immediately to the pad array. */
+ src = pptr;
+ sptr = NULL;
+ sdim = pdim;
+ for (dim = 0; dim < pdim; dim++)
+ {
+ scount[dim] = pcount[dim];
+ sextent[dim] = pextent[dim];
+ sstride[dim] = pstride[dim];
+ sstride0 = sstride[0] * sizeof (rtype_name);
+ }
+ }
+
while (rptr)
{
/* Select between the source and pad arrays. */
src += sstride0;
rcount[0]++;
scount[0]++;
+
/* Advance to the next destination element. */
n = 0;
while (rcount[n] == rextent[n])
the next dimension. */
rcount[n] = 0;
/* We could precalculate these products, but this is a less
- frequently used path so proabably not worth it. */
+ frequently used path so probably not worth it. */
rptr -= rstride[n] * rextent[n];
n++;
if (n == rdim)
the next dimension. */
scount[n] = 0;
/* We could precalculate these products, but this is a less
- frequently used path so proabably not worth it. */
+ frequently used path so probably not worth it. */
src -= sstride[n] * sextent[n];
n++;
if (n == sdim)
}
}
}
+
+#endif