header:
#include <iostream>

class Int17Matrix3D {
public:

  Int17Matrix3D(int x, int y, int z);

  Int17Matrix3D(const Int17Matrix3D& other);

  ~Int17Matrix3D();

  Int17Matrix3D& operator=(int32_t value);  

  Int17Matrix3D& operator=(const Int17Matrix3D& other);

  static Int17Matrix3D make_array(int x, int y, int z);

  void copy(int32_t* array1, const int32_t* array2, int size);

  void SetValueAtCurrentIndex(int32_t value);

  class Proxy3D;
  class Proxy2D;
  class Proxy1D;

  Proxy2D operator[](int x);

  void SetValueAtIndex(int x, int y, int z, int32_t value);
  int32_t GetValueAtIndex(int x, int y, int z) const;

  Int17Matrix3D operator+(const Int17Matrix3D& other);

  Int17Matrix3D operator-(const Int17Matrix3D& other);

  Int17Matrix3D operator*(int32_t mult);

private:
  const int8_t kNumLenght_ = 17;
  int32_t current_index_;
  int32_t max_index_;
  int32_t width_;
  int32_t height_;
  int32_t depth_;
  int32_t* array_;
  int32_t current_x_ = 0;
  int32_t current_y_ = 0;
  int32_t current_z_ = 0;

  bool TakeBit(const int32_t* value, uint32_t bit_position) const;

  Int17Matrix3D& ClearBit(int32_t* value, int32_t bit_position);

  Int17Matrix3D& SetBit(int32_t* value, int32_t bit_position);

  int GetIndex(int x, int y, int z) const;

  int32_t ToDecimal(const int32_t* array_, int32_t current_index_) const;

  friend std::ostream& operator<<(std::ostream& stream, const Int17Matrix3D& array);

  friend std::istream& operator>>(std::istream& stream, const Int17Matrix3D& array);

  friend bool operator==(const Int17Matrix3D& lhs, const Int17Matrix3D& rhs);

  friend bool operator!=(const Int17Matrix3D& lhs, const Int17Matrix3D& rhs);
};

class Int17Matrix3D::Proxy3D {
    Int17Matrix3D& parentMatrix_;
    int x_, y_, z_;

public:
    Proxy3D(Int17Matrix3D& parentMatrix_, int x, int y, int z)
        : parentMatrix_(parentMatrix_), x_(x), y_(y), z_(z) {}

    Proxy3D& operator=(int value) {
        parentMatrix_.SetValueAtIndex(x_, y_, z_, value);
        return *this;
    }

    operator int() const {
        return parentMatrix_.GetValueAtIndex(x_, y_, z_);
    }
};

class Int17Matrix3D::Proxy2D {
  Int17Matrix3D& parentMatrix_;
  int x_;

public:
  Proxy2D(Int17Matrix3D& parentMatrix_, int x) : parentMatrix_(parentMatrix_), x_(x) {}

  Proxy1D operator[](int y);
};

class Int17Matrix3D::Proxy1D {
  Int17Matrix3D& parentMatrix_;
  int x_, y_;

public:
  Proxy1D(Int17Matrix3D& parentMatrix_, int x, int y) : parentMatrix_(parentMatrix_), x_(x), y_(y) {}
  Proxy3D operator[](int z) {
        return Proxy3D(parentMatrix_, x_, y_, z);
    }
};


cpp:
#include <iostream>
#include "Int17Matrix3D.h"

Int17Matrix3D::Int17Matrix3D(int x, int y, int z) : width_(x), height_(y), depth_(z), array_(new int32_t[kNumLenght_ * x * y * z]){}

Int17Matrix3D::Int17Matrix3D(const Int17Matrix3D& other) : width_(other.width_), height_(other.height_), depth_(other.depth_), array_(new int32_t[kNumLenght_ * width_ * height_ * depth_]) {
    copy(array_, other.array_, kNumLenght_ * width_ * height_ * depth_);
}
Int17Matrix3D::~Int17Matrix3D() { delete[] array_; }

Int17Matrix3D& Int17Matrix3D::operator=(const Int17Matrix3D& other) {
  if (this != &other) {
    delete[] array_;
    width_ = other.width_;
    height_ = other.height_;
    depth_ = other.depth_;
    current_index_ = other.current_index_;
    max_index_ = other.max_index_;
    current_x_ = other.current_x_; 
    current_y_ = other.current_y_;
    current_z_ = other.current_z_;
    array_ = new int32_t[kNumLenght_ * width_ * height_ * depth_];
    copy(array_, other.array_, kNumLenght_ * width_ * height_ * depth_);
  }
  return *this;
}

Int17Matrix3D Int17Matrix3D::make_array(int x, int y, int z) {
  return Int17Matrix3D(x, y, z);
}

Int17Matrix3D& Int17Matrix3D::operator=(int32_t value) {
  int first_bit_index = current_index_ * kNumLenght_;

  for (int i = 0; i < kNumLenght_; ++i) {
    if (value & (1 << i)) {
      SetBit(array_, first_bit_index + i);
    } else {
      ClearBit(array_, first_bit_index + i);
    }
  }
  return *this;
}

void Int17Matrix3D::copy(int32_t* array1, const int32_t* array2, int size) {
  for (int i = 0; i < size; ++i) {
    array1[i] = array2[i];
  }
}

void Int17Matrix3D::SetValueAtCurrentIndex(int32_t value) {
    (*this)[current_x_][current_y_][current_z_] = value;
}

bool Int17Matrix3D::TakeBit(const int32_t* value, uint32_t bit_position) const {
  int array_index = bit_position / 32;
  int bit_index = bit_position % 32;
  return ((value[array_index] >> bit_index) & 1) != 0;
}

Int17Matrix3D& Int17Matrix3D::ClearBit(int32_t* value, int32_t bit_position) {
  value[bit_position / 32] &= ~(1 << (bit_position % 32));
  return *this;
}

Int17Matrix3D& Int17Matrix3D::SetBit(int32_t* value, int32_t bit_position) {
  value[bit_position / 32] |= (1 << (bit_position % 32));
  return *this;
}

int Int17Matrix3D::GetIndex(int x, int y, int z) const {
  return x + y * (width_ * kNumLenght_) + z * (width_ * height_ * kNumLenght_);
}

int32_t Int17Matrix3D::ToDecimal(const int32_t* array_, int32_t current_index_) const {
  int first_bit_index = current_index_ * kNumLenght_;
  int32_t decimal_value = 0;
  int32_t exp = 1;

  for (int i = 0; i < kNumLenght_; ++i) {
    if (TakeBit(array_, first_bit_index + i)) {
      decimal_value += exp;
    }
    exp <<= 1;
  }

  return decimal_value;
}

Int17Matrix3D Int17Matrix3D::operator+(const Int17Matrix3D& other) {
  if (this->width_ != other.width_ || this->height_ != other.height_ || this->depth_ != other.depth_) {
    throw std::out_of_range("Arrays must be with the same size");
  }

  Int17Matrix3D result(this->width_, this->height_, this->depth_);

  for (int z = 0; z < this->depth_; ++z) {
    for (int y = 0; y < this->height_; ++y) {
      for (int x = 0; x < this->width_; ++x) {
        int index = this->GetIndex(x, y, z);
        result[x][y][z] = this->ToDecimal(this->array_, index) + other.ToDecimal(other.array_, index);
      }
    }
  }
  return result;
}

Int17Matrix3D Int17Matrix3D::operator-(const Int17Matrix3D& other) {
  if (this->width_ != other.width_ || this->height_ != other.height_ || this->depth_ != other.depth_) {
    throw std::out_of_range("Arrays must be with the same size");
  }

  Int17Matrix3D result(this->width_, this->height_, this->depth_);

  for (int z = 0; z < this->depth_; ++z) {
    for (int y = 0; y < this->height_; ++y) {
      for (int x = 0; x < this->width_; ++x) {
        int index = this->GetIndex(x, y, z);
        result[x][y][z] = this->ToDecimal(this->array_, index) - other.ToDecimal(other.array_, index);
      }
    }
  }
  return result;
}

Int17Matrix3D Int17Matrix3D::operator*(int32_t mult) {
  Int17Matrix3D result(this->width_, this->height_, this->depth_);

  for (int z = 0; z < this->depth_; ++z) {
    for (int y = 0; y < this->height_; ++y) {
      for (int x = 0; x < this->width_; ++x) {
        int index = this->GetIndex(x, y, z);
        result[x][y][z] = this->ToDecimal(this->array_, index) * mult;
      }
    }
  }
  return result;
}

bool operator==(const Int17Matrix3D& lhs, const Int17Matrix3D& rhs) {
  return lhs.ToDecimal(lhs.array_, lhs.current_index_) == rhs.ToDecimal(rhs.array_, rhs.current_index_);
}

bool operator!=(const Int17Matrix3D& lhs, const Int17Matrix3D& rhs) {
  return !(lhs == rhs);
}

std::ostream& operator<<(std::ostream& stream, const Int17Matrix3D& matrix) {
  int32_t value = matrix.ToDecimal(matrix.array_, matrix.current_index_);
  stream << value;
  return stream;
}

std::istream& operator>>(std::istream& stream, Int17Matrix3D& array) {
  int32_t value;
  stream >> value;

  if (!stream) return stream;

  array.SetValueAtCurrentIndex(value);

  return stream;
}

Int17Matrix3D::Proxy2D Int17Matrix3D::operator[](int x) {
  if (x < 0 || x >= this->width_) {
        throw std::out_of_range("Index out of range in y-dimension");
    }
  return Proxy2D(*this, x);
}

Int17Matrix3D::Proxy1D Int17Matrix3D::Proxy2D::operator[](int y) {
    if (y < 0 || y >= parentMatrix_.height_) {
        throw std::out_of_range("Index out of range in y-dimension");
    }
    return Proxy1D(parentMatrix_, x_, y);
}


void Int17Matrix3D::SetValueAtIndex(int x, int y, int z, int32_t value) {
  int index = GetIndex(x, y, z);
  int bit_offset = index * kNumLenght_;

    // Clear previous value
  for (int bit = 0; bit < kNumLenght_; ++bit) {
    ClearBit(array_, bit_offset + bit);
    }

    // Set new value
    for (int bit = 0; bit < kNumLenght_; ++bit) {
      if (value & (1 << bit)) {
      SetBit(array_, bit_offset + bit);
    }
  }
}

int32_t Int17Matrix3D::GetValueAtIndex(int x, int y, int z) const {
  int index = GetIndex(x, y, z);
  return ToDecimal(array_, index * kNumLenght_);
}



tests:
#include <gtest/gtest.h>
#include <lib/Int17Matrix3D.h>

TEST(Int17Matrix3DTest, Constructor) {
  Int17Matrix3D matrix(2, 2, 2);
  ASSERT_NO_THROW();
}

TEST(Int17Matrix3DTest, make_array) {
  Int17Matrix3D matrix = Int17Matrix3D::make_array(2, 2, 2);
  ASSERT_NO_THROW();
}

TEST(Int17Matrix3DTest, CopyConstructor) {
  Int17Matrix3D original(1, 2, 3);
  ASSERT_NO_THROW(Int17Matrix3D copy = original);
}

TEST(Int17Matrix3DTest, ParenthesesOperator_EqTest) {
  Int17Matrix3D matrix(3, 3, 3);
  matrix[1][1][1] = 5;
  ASSERT_EQ(matrix[1][1][1], 5);
}

TEST(Int17Matrix3DTest, ParenthesesOperator_NonEqTest) {
  Int17Matrix3D matrix(3, 3, 3);
  matrix[1][1][1] = 5;
  ASSERT_NE(matrix[1][1][1], 7);
}

TEST(Int17Matrix3DTest, ParenthesesOperator_BoundsCheck) {
  Int17Matrix3D matrix(2, 2, 2);
  ASSERT_THROW(matrix[3][1][1] = 5, std::out_of_range);
  ASSERT_THROW(matrix[1][3][1] = 5, std::out_of_range);
  ASSERT_THROW(matrix[1][1][3] = 5, std::out_of_range);
}

TEST(Int17Matrix3DTest, EqualOperator_TwoEq) {
  Int17Matrix3D arr1(1, 1, 1);
  Int17Matrix3D arr2(2, 2, 2);
  arr1[0][0][0] = 10;
  arr2[0][0][0] = 10;
  arr2[1][1][1] = 10;
  ASSERT_EQ(arr1[0][0][0], arr2[0][0][0]);
  ASSERT_EQ(arr1[0][0][0], arr2[1][1][1]);
}

TEST(Int17Matrix3DTest, EqualOperator_NonEq) {
  Int17Matrix3D arr1(1, 1, 1);
  Int17Matrix3D arr2(1, 1, 1);
  arr1[0][0][0] = 1;
  arr2[0][0][0] = 3;
  ASSERT_NE(arr1[0][0][0], arr2[0][0][0]);
}

TEST(Int17Matrix3DTest, AssignmentOperator_NoThrow) {
  Int17Matrix3D arr1(1, 2, 3);
  Int17Matrix3D arr2(2, 2, 2);
  ASSERT_NO_THROW(arr2 = arr1);
}

TEST(Int17Matrix3DTest, AssignmentOperator_Trow) {
  Int17Matrix3D arr1(1, 2, 3);
  Int17Matrix3D arr2(2, 2, 2);
  arr2 = arr1;
  ASSERT_THROW(arr2[1][1][1], std::out_of_range);
}

TEST(Int17Matrix3DTest, AssignmentOperator) {
  Int17Matrix3D arr1(1, 2, 3);
  Int17Matrix3D arr2(2, 2, 2);
  arr1[0][1][2] = 5;
  arr2[0][0][0] = 3;
  arr2 = arr1;
  ASSERT_EQ(arr2[0][1][2], 5);
  ASSERT_NE(arr2[0][0][0], 3);
}

TEST(Int17Matrix3DTest, Addition_EmptyArrays) {
  Int17Matrix3D arr1(1, 1, 1);
  Int17Matrix3D arr2(1, 1, 1);
  Int17Matrix3D arr3 = arr1 + arr2;
  ASSERT_EQ(arr3[0][0][0], 0);
}

TEST(Int17Matrix3DTest, Addition_SingleCells) {
  Int17Matrix3D arr1(1, 1, 1);
  Int17Matrix3D arr2(1, 1, 1);
  arr1[0][0][0] = 1;
  arr2[0][0][0] = 2;
  Int17Matrix3D arr3 = arr1 + arr2;
  ASSERT_EQ(arr3[0][0][0], 3);
}

TEST(Int17Matrix3DTest, Addition_FewCells) {
  Int17Matrix3D arr1(1, 1, 2);
  Int17Matrix3D arr2(1, 1, 2);
  arr1[0][0][1] = 1;
  arr1[0][0][0] = 5;
  arr2[0][0][0] = 2;
  arr2[0][0][1] = 0;
  Int17Matrix3D arr3 = arr1 + arr2;
  ASSERT_EQ(arr3[0][0][0], 7);
  ASSERT_EQ(arr3[0][0][1], 1);
}

TEST(Int17Matrix3DTest, Addition_DifferentSize) {
  Int17Matrix3D arr1(1, 1, 1);
  Int17Matrix3D arr2(1, 1, 2);
  arr1[0][0][0] = 1;
  arr2[0][0][0] = 2;
  ASSERT_THROW(Int17Matrix3D arr3 = arr1 + arr2, std::out_of_range);
}

TEST(Int17Matrix3DTest, Substraction_EmptyArrays) {
  Int17Matrix3D arr1(1, 1, 1);
  Int17Matrix3D arr2(1, 1, 1);
  Int17Matrix3D arr3 = arr1 - arr2;
  ASSERT_EQ(arr3[0][0][0], 0);
}

TEST(Int17Matrix3DTest, Substraction_SingleCells) {
  Int17Matrix3D arr1(1, 1, 1);
  Int17Matrix3D arr2(1, 1, 1);
  arr1[0][0][0] = 7;
  arr2[0][0][0] = 2;
  Int17Matrix3D arr3 = arr1 - arr2;
  ASSERT_EQ(arr3[0][0][0], 5);
}

TEST(Int17Matrix3DTest, Substraction_FewCells) {
  Int17Matrix3D arr1(1, 1, 2);
  Int17Matrix3D arr2(1, 1, 2);
  arr1[0][0][1] = 3;
  arr1[0][0][0] = 5;
  arr2[0][0][0] = 2;
  Int17Matrix3D arr3 = arr1 - arr2;
  ASSERT_EQ(arr3[0][0][0], 3);
  ASSERT_EQ(arr3[0][0][1], 3);
}

TEST(Int17Matrix3DTest, Multiplication_ByZero) {
  Int17Matrix3D arr1(2, 2, 2);
  arr1[0][0][0] = 1;
  arr1[0][0][1] = 2;
  arr1[0][1][0] = 3;
  arr1[0][1][1] = 4;
  arr1[1][0][0] = 5;
  arr1[1][0][1] = 6;
  arr1[1][1][0] = 7;
  arr1[1][1][1] = 8;
  int mult = 0;
  Int17Matrix3D arr3 = arr1 * mult;
  ASSERT_EQ(arr3[0][0][0], 0);
  ASSERT_EQ(arr3[0][0][1], 0);
  ASSERT_EQ(arr3[0][1][0], 0);
  ASSERT_EQ(arr3[0][1][1], 0);
  ASSERT_EQ(arr3[1][0][0], 0);
  ASSERT_EQ(arr3[1][0][1], 0);
  ASSERT_EQ(arr3[1][1][0], 0);
  ASSERT_EQ(arr3[1][1][1], 0);
}

TEST(Int17Matrix3DTest, Multiplication) {
  Int17Matrix3D arr1(2, 2, 2);
  Int17Matrix3D arr2 (2, 2, 2);
  arr1[0][0][0] = 1;
  arr1[0][0][1] = 2;
  arr1[0][1][0] = 3;
  arr1[0][1][1] = 4;
  arr1[1][0][0] = 5;
  arr1[1][0][1] = 6;
  arr1[1][1][0] = 7;
  arr1[1][1][1] = 8;
  int mult = 10;
  arr2 = arr1 * mult;
  ASSERT_EQ(arr2[0][0][0], 10);
  ASSERT_EQ(arr2[0][0][1], 20);
  ASSERT_EQ(arr2[0][1][0], 30);
  ASSERT_EQ(arr2[0][1][1], 40);
  ASSERT_EQ(arr2[1][0][0], 50);
  ASSERT_EQ(arr2[1][0][1], 60);
  ASSERT_EQ(arr2[1][1][0], 70);
  ASSERT_EQ(arr2[1][1][1], 80);
}


The following tests FAILED:
          4 - Int17Matrix3DTest.ParenthesesOperator_EqTest (Failed)
          6 - Int17Matrix3DTest.ParenthesesOperator_BoundsCheck (Failed)
          7 - Int17Matrix3DTest.EqualOperator_TwoEq (Failed)
         11 - Int17Matrix3DTest.AssignmentOperator (Failed)
         14 - Int17Matrix3DTest.Addition_FewCells (Failed)
         18 - Int17Matrix3DTest.Substraction_FewCells (Failed)
         20 - Int17Matrix3DTest.Multiplication (Failed)


испарвь ошибки они все связаны с оператором[]