@Override
  public CompoundIntegerDataset getSlice(final SliceIterator siter) {
    CompoundIntegerDataset result = new CompoundIntegerDataset(isize, siter.getSliceShape());
    int[] rdata = result.data; // PRIM_TYPE
    IndexIterator riter = result.getIterator();

    while (siter.hasNext() && riter.hasNext()) {
      for (int i = 0; i < isize; i++) rdata[riter.index + i] = data[siter.index + i];
    }

    result.setName(name + ".slice");
    return result;
  }
  @Override
  public StringDatasetBase getSlice(final SliceIterator siter) {
    StringDatasetBase result = new StringDatasetBase(siter.getShape());
    String[] rdata = result.data; // PRIM_TYPE

    for (int i = 0; siter.hasNext(); i++) rdata[i] = data[siter.index];

    result.setName(
        name
            + BLOCK_OPEN
            + Slice.createString(siter.shape, siter.start, siter.stop, siter.step)
            + BLOCK_CLOSE);
    return result;
  }
  @Override
  public void setItemsOnAxes(final int[] pos, final boolean[] axes, final Object src) {
    String[] sdata = (String[]) src; // PRIM_TYPE

    SliceIterator siter = getSliceIteratorFromAxes(pos, axes);

    if (sdata.length < calcSize(siter.getShape())) {
      throw new IllegalArgumentException("destination array is not large enough");
    }

    for (int i = 0; siter.hasNext(); i++) {
      data[siter.index] = sdata[i];
    }
    setDirty();
  }
  @Override
  public void copyItemsFromAxes(final int[] pos, final boolean[] axes, final Dataset dest) {
    String[] ddata = (String[]) dest.getBuffer(); // PRIM_TYPE

    SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
    int[] sshape = squeezeShape(siter.getShape(), false);

    IndexIterator diter = dest.getSliceIterator(null, sshape, null);

    if (ddata.length < calcSize(sshape)) {
      throw new IllegalArgumentException("destination array is not large enough");
    }

    while (siter.hasNext() && diter.hasNext()) ddata[diter.index] = data[siter.index];
  }
  @Override
  public void setItemsOnAxes(final int[] pos, final boolean[] axes, final Object src) {
    int[] sdata = (int[]) src; // PRIM_TYPE

    SliceIterator siter = getSliceIteratorFromAxes(pos, axes);

    if (sdata.length < calcSize(siter.getSliceShape())) {
      throw new IllegalArgumentException("source array is not large enough");
    }

    for (int i = 0; siter.hasNext(); i++) {
      for (int j = 0; j < isize; j++) data[siter.index + j] = sdata[isize * i + j];
    }

    setDirty();
  }
  @Override
  public void copyItemsFromAxes(final int[] pos, final boolean[] axes, final AbstractDataset dest) {
    int[] ddata = (int[]) dest.odata; // PRIM_TYPE

    if (dest.getElementsPerItem() != isize) {
      throw new IllegalArgumentException(
          String.format(
              "Destination dataset is incompatible as it has %d elements per item not %d",
              dest.getElementsPerItem(), isize));
    }

    SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
    int[] sshape = squeezeShape(siter.getSliceShape(), false);

    IndexIterator diter = dest.getSliceIterator(null, sshape, null);

    if (ddata.length < calcSize(sshape)) {
      throw new IllegalArgumentException("destination array is not large enough");
    }

    while (siter.hasNext() && diter.hasNext()) {
      for (int i = 0; i < isize; i++) ddata[diter.index + i] = data[siter.index + i];
    }
  }
  @Override
  public CompoundIntegerDataset setSlice(final Object o, final SliceIterator siter) {
    if (o instanceof IDataset) {
      final IDataset ds = (IDataset) o;
      final int[] oshape = ds.getShape();

      if (!areShapesCompatible(siter.getSliceShape(), oshape)) {
        throw new IllegalArgumentException(
            String.format(
                "Input dataset is not compatible with slice: %s cf %s",
                Arrays.toString(oshape), Arrays.toString(siter.getSliceShape())));
      }

      if (ds instanceof AbstractDataset) {
        final AbstractDataset ads = (AbstractDataset) ds;
        IndexIterator oiter = ads.getIterator();

        if (ds instanceof AbstractCompoundDataset) {
          if (isize != ads.getElementsPerItem()) {
            throw new IllegalArgumentException("Input dataset is not compatible with slice");
          }

          while (siter.hasNext() && oiter.hasNext()) {
            for (int i = 0; i < isize; i++)
              data[siter.index + i] =
                  (int) ads.getElementLongAbs(oiter.index + i); // GET_ELEMENT_WITH_CAST
          }
        } else {
          while (siter.hasNext() && oiter.hasNext()) {
            data[siter.index] = (int) ads.getElementLongAbs(oiter.index); // GET_ELEMENT_WITH_CAST
            for (int i = 1; i < isize; i++) data[siter.index + i] = 0;
          }
        }
      } else {
        final IndexIterator oiter = new PositionIterator(oshape);
        final int[] pos = oiter.getPos();

        if (ds.getElementsPerItem() == 1) {
          while (siter.hasNext() && oiter.hasNext()) {
            data[siter.index] = ds.getInt(pos); // PRIM_TYPE
            for (int i = 1; i < isize; i++) data[siter.index + i] = 0;
          }
        } else {
          while (siter.hasNext() && oiter.hasNext()) {
            final int[] val = toIntegerArray(ds.getObject(pos), isize); // PRIM_TYPE // CLASS_TYPE
            for (int i = 0; i < isize; i++) data[siter.index + i] = val[i];
          }
        }
      }
    } else {
      try {
        final int[] vr = toIntegerArray(o, isize); // PRIM_TYPE // CLASS_TYPE

        while (siter.hasNext()) {
          for (int i = 0; i < isize; i++) data[siter.index + i] = vr[i];
        }
      } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException("Object for setting slice is not a dataset or number");
      }
    }
    setDirty();
    return this;
  }