     
     init(_ tensor:Tensor, dimIndex:[Int]?=nil, view:StorageView<StorageType>?=nil, stride: [Int]?=nil, copy:Bool=false) {
         if copy {
+            self.view = view ?? ViewType(shape: tensor.shape, offset: tensor.view.offset)
             storage = StorageType(size: tensor.shape.elements, value: 0)
             for i in 0..<tensor.shape.elements {
                 storage[i] = tensor.storage[i]
             }
         } else {
+            // NB: If making a copy, previously defined offset is no longer valid
+            self.view = view ?? ViewType(shape: tensor.shape, offset: Array<Int>(repeating: 0, count: tensor.dims))
             storage = tensor.storage
         }
         
+        offset = 0
         internalShape = tensor.internalShape
-        offset = 0
-        
-        if let d = dimIndex {
-            self.dimIndex = d
-        } else {
-            self.dimIndex = tensor.dimIndex
-        }
-        
-        if let v = view {
-            self.view = v
-        } else {
-            if !copy {
-                self.view = ViewType(shape: tensor.shape, offset: tensor.view.offset)
-            } else {
-                // if we're making a copy, then the previously defined offset in the original Tensor
-                // is no longer correct
-                self.view = ViewType(shape: tensor.shape, offset: Array<Int>(repeating: 0, count: tensor.dims))
-            }
-        }
-        
-        if let s = stride {
-            self.stride = s
-        } else {
-            self.stride = tensor.stride
-        }
+        self.view = view ?? ViewType(shape: tensor.shape, offset: copy ? tensor.view.offset : Array<Int>(repeating: 0, count: tensor.dims))
+        self.dimIndex = dimIndex ?? tensor.dimIndex
+        self.stride = stride ?? tensor.stride
     }
     
     init(tensor:Tensor, shape:Extent, stride:[Int]) {

    // Defaults to given indices in native layout (to allow for better performance). However,
    // if consistency in traversal between storage types is required, the order can be specified
    open func indices(_ order:DimensionOrder?=nil) -> IteratorSequence<IndexGenerator> {
        if let o = order {
            return IteratorSequence<IndexGenerator>(IndexGenerator(shape, order: o))
        } else {
            return IteratorSequence<IndexGenerator>(IndexGenerator(shape, order: storage.order))
        }
    }
}


            let values:[String] = (0..<shape[dim]).map({(i:Int) -> String in
                idx[dim] = i
                
                let indent:String = i > 0 ? String(repeating: " ", count: dim+1) : ""
                return "\(indent)\(convertToString(idx, dim: dim+1))"
            })
            return "[\(values.joined(separator: "\n"))]"
