#include <iostream>

class UtoplyusVKostrule {
public:
  UtoplyusVKostrule(int x, int y, int z) : width_(x), height_(y), depth_(z) {
    arr_ = new int32_t[kNumLenght_ * x * y * z];
    std::memset(arr_, 0, kNumLenght_ * x * y * z * sizeof(int32_t));
  }

  ~UtoplyusVKostrule() {
    delete[] arr_;
  }

  UtoplyusVKostrule(const UtoplyusVKostrule& other) : width_(other.width_), height_(other.height_), depth_(other.depth_) {
    arr_ = new int32_t[kNumLenght_ * width_ * height_ * depth_];
    std::memcpy(arr_, other.arr_, kNumLenght_ * width_ * height_ * depth_ * sizeof(int32_t));
  }

  UtoplyusVKostrule& operator=(const UtoplyusVKostrule& other) {
    if (this != &other) {
        delete[] arr_;
        width_ = other.width_;
        height_ = other.height_;
        depth_ = other.depth_;
        arr_ = new int32_t[kNumLenght_ * width_ * height_ * depth_];
        std::memcpy(arr_, other.arr_, kNumLenght_ * width_ * height_ * depth_ * sizeof(int32_t));
    }
    return *this;
  } 

  static UtoplyusVKostrule make_array(int x, int y, int z) {
    return UtoplyusVKostrule(x, y, z);
  }

  UtoplyusVKostrule& operator()(int x, int y, int z) {
    current_index_ = x + y * width_ + z * width_ * height_;
    return *this;
  }

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

    char* c_value = new char[kNumLenght_];
    int a = -1;

    while (value != 0) {
      c_value[++a] = (value % 2) + '0';
      value /= 2;
    }

    for (int i = 0; i < kNumLenght_; ++i) {
      if (c_value[i] - '0') {
        SetBit(arr_, first_bit_index + i);
      }
    }

    delete[] c_value;
    return *this;
  }

private:
  const int8_t kNumLenght_ = 17;
  int32_t current_index_;
  int32_t width_;
  int32_t height_;
  int32_t depth_;
  int32_t* arr_;

  bool TakeBit(const int32_t* value, uint32_t bit_position) {
    return (value[bit_position / 32] >> (bit_position % 32)) & 1;
  }

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

  int32_t ToDec(int32_t* arr_, int32_t current_index_) const {
    int first_bit_index = current_index_ * kNumLenght_;

    int32_t decimal_value = 0;
    int32_t exp = 1;

    for (int i = first_bit_index + kNumLenght_ - 1; i >= first_bit_index; --i) {
      decimal_value += (arr_[i / 32] >> (i % 32) & 1) * exp;
      exp *= 2;
    }

    return decimal_value;
  }

  UtoplyusVKostrule& TwoImplement(int32_t* arr_) {
    int32_t current_value = ToDec(arr_, current_index_);
    int32_t inverted_value = ~current_value;
    int32_t new_value = inverted_value + 1;

    for (int i = 0; i < kNumLenght_; ++i) {
      arr_[current_index_ / 32] = (arr_[current_index_ / 32] & ~(1 << (current_index_ % 32))) | ((new_value & 1) << (current_index_ % 32));
    }

    return *this;
  }

  friend UtoplyusVKostrule& operator+(const UtoplyusVKostrule& lhs, const UtoplyusVKostrule& rhs);

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

UtoplyusVKostrule& operator+(const UtoplyusVKostrule& lhs, const UtoplyusVKostrule& rhs) {
  if (lhs.width_ != rhs.width_ || lhs.height_ != rhs.height_ || lhs.depth_ != rhs.depth_) {
    throw std::invalid_argument("Dimensions of both arrays must match");
  }

  UtoplyusVKostrule result(lhs.width_, lhs.height_, lhs.depth_);

  for (int z = 0; z < lhs.depth_; ++z) {
    for (int y = 0; y < lhs.height_; ++y) {
      for (int x = 0; x < lhs.width_; ++x) {
        int32_t decimal_lhs = lhs.ToDec(lhs.arr_, x + y * lhs.width_ + z * lhs.width_ * lhs.height_);
        int32_t decimal_rhs = rhs.ToDec(rhs.arr_, x + y * rhs.width_ + z * rhs.width_ * rhs.height_);

        result(x, y, z) = decimal_lhs + decimal_rhs;
      }
    }
  }

  return result;
}

std::ostream& operator<<(std::ostream& stream, const UtoplyusVKostrule& array) {
  int32_t decimal_value = array.ToDec(array.arr_, array.current_index_);
  stream << decimal_value;

  return stream;
}

int main() {
  UtoplyusVKostrule a = UtoplyusVKostrule::make_array(1, 1, 1);
  UtoplyusVKostrule b = UtoplyusVKostrule::make_array(1, 1, 1);
  UtoplyusVKostrule c = UtoplyusVKostrule::make_array(1, 1, 1);
  a(1, 1, 1) = 2;
  b(1, 1, 1) = 4;
  c = a + b;
  std::cout << c(1, 1, 1);
}
/bin/sh: line 1: 17202 Segmentation fault: 11  "/Users/alex/labwork5-SPLOIT47/lib/"main
исправь