   typedef ptrdiff_t index_t[ndim];
 
 public:
+  // Constructor supports pointers or initializer lists and index is optional
+  //    CIndexer<3> ca(shape, index);
+  //    CIndexer<3> ca({1, 2, 3}, {0, 1, 1});
+  //    CIndexer<3> ca = {1, 2, 3};
+  // Initializer lists are only supported with -std=c++11 or higher.
+
+  template <typename Int>
+  __device__ explicit CIndexer(const Int* shape)
+      : size_(1) {
+    for (int i = 0; i < _ndim; i++) {
+      this->size_ *= shape[i];
+      this->shape_[i] = shape[i];
+      this->index_[i] = 0;
+    }
+  }
+
+  template <typename Int1, typename Int2>
+  __device__ CIndexer(const Int1* shape, const Int2* index)
+      : size_(1) {
+    for (int i = 0; i < _ndim; i++) {
+      this->size_ *= shape[i];
+      this->shape_[i] = shape[i];
+      this->index_[i] = index[i];
+    }
+  }
+
+#if __cplusplus >= 201103
+  template <typename Int>
+  __device__ CIndexer(const std::initializer_list<Int> shape)
+      : CIndexer(shape.begin())
+  {
+    assert(shape.size() == _ndim);
+  }
+
+  template <typename Int1, typename Int2>
+  __device__ CIndexer(const std::initializer_list<Int1> shape,
+                      const std::initializer_list<Int2> index)
+      : CIndexer(shape.begin(), index.begin())
+  {
+    assert(shape.size() == _ndim);
+    assert(index.size() == _ndim);
+  }
+#endif
+
   __device__ ptrdiff_t size() const {
     return size_;
   }

#pragma once

// math
#ifndef M_PI

  __device__ const ptrdiff_t* strides() const {
    return strides_;
  }

#if __cplusplus >= 201103
  template <typename Int>
  __device__ T& operator[](const std::initializer_list<Int> idx_) {
    assert(idx_.size() == _ndim);
    Int idx[ndim];
    memcpy(idx, idx_.begin(), ndim*sizeof(Int));
    return this->operator[](idx);
  }

  template <typename Int>
  __device__ const T& operator[](const std::initializer_list<Int> idx_) const {
    assert(idx_.size() == _ndim);
    Int idx[ndim];
    memcpy(idx, idx_.begin(), ndim*sizeof(Int));
    return this->operator[](idx);
  }
#endif

  template <typename Int>
  __device__ T& operator[](const Int (&idx)[ndim]) {
