--- /dev/null
+#ifndef __NNCC_CORE_ADT_TENSOR_INDEX_H__
+#define __NNCC_CORE_ADT_TENSOR_INDEX_H__
+
+#include <vector>
+#include <cstdint>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+class Index
+{
+public:
+ uint32_t rank(void) const;
+
+public:
+ Index &resize(uint32_t size);
+
+public:
+ uint32_t &at(uint32_t axis);
+ uint32_t at(uint32_t axis) const;
+
+private:
+ std::vector<uint32_t> _indices;
+};
+
+} // namespace tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
+
+#endif // __NNCC_CORE_ADT_TENSOR_INDEX_H__
--- /dev/null
+#include "nncc/core/ADT/tensor/Index.h"
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+uint32_t Index::rank(void) const { return _indices.size(); }
+Index &Index::resize(uint32_t size) { _indices.resize(size); }
+
+uint32_t &Index::at(uint32_t axis) { return _indices.at(axis); }
+uint32_t Index::at(uint32_t axis) const { return _indices.at(axis); }
+
+} // namespace tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
--- /dev/null
+#include "nncc/core/ADT/tensor/Index.h"
+
+#include <gtest/gtest.h>
+
+TEST(ADT_TENSOR_INDEX, ctor)
+{
+ nncc::core::ADT::tensor::Index index;
+
+ ASSERT_EQ(index.rank(), 0);
+}
+
+TEST(ADT_TENSOR_INDEX, resize)
+{
+ nncc::core::ADT::tensor::Index index;
+
+ index.resize(4);
+
+ ASSERT_EQ(index.rank(), 4);
+}
+
+TEST(ADT_TENSOR_INDEX, at)
+{
+ nncc::core::ADT::tensor::Index index;
+
+ index.resize(4);
+
+ uint32_t indices[4] = {3, 5, 2, 7};
+
+ for (uint32_t axis = 0; axis < 4; ++axis)
+ {
+ index.at(axis) = indices[axis];
+ ASSERT_EQ(index.at(axis), indices[axis]);
+ }
+}
+
+TEST(ADT_TENSOR_INDEX, copy)
+{
+ nncc::core::ADT::tensor::Index original;
+
+ original.resize(4);
+
+ uint32_t indices[4] = {3, 5, 2, 7};
+
+ for (uint32_t axis = 0; axis < 4; ++axis)
+ {
+ original.at(axis) = indices[axis];
+ }
+
+ const nncc::core::ADT::tensor::Index copied{original};
+
+ ASSERT_EQ(original.rank(), copied.rank());
+
+ for (uint32_t axis = 0; axis < 4; ++axis)
+ {
+ ASSERT_EQ(original.at(axis), copied.at(axis));
+ }
+}