#include <iostream>
#include <vector>

using namespace std;
template<typename... Args>
void special_printf(Args ... args) {
  printf("Danger, printing: ");
  printf(args...);
}

template<class T>
class svector : public vector<T> {

  struct SafeRef {
    T* pointer;

    SafeRef(T* init) {
      pointer = init;
    }

    SafeRef& operator=(const T& val) {
      if (pointer) *pointer = val;
      return *this;
    }  

    operator T() {
      if (pointer) return *pointer;
      return T();
    }
  };

  struct LenProxy {
    //vector<T> *ptr;

    //LenProxy(vector<T>* init) {
      //ptr = init;
    //}

    //void set(vector<T>*init) {ptr=init;}

    // svector ( vector , xxxxx, LenProxy )
    //                           ^ 

    vector<T> * parent() {
      return reinterpret_cast<vector<T> *>(
        reinterpret_cast<char*>(this) - offsetof(svector, length));
    }

    LenProxy& operator=(size_t new_size) {
      parent()->resize(new_size);
      return *this;
    }

    operator size_t() {
      return parent()->size();
    }
  };

public:

  template<typename ... Args>
  svector(Args&& ... args) : vector<T>(args ...)/*, length(this)*/{
  }

  SafeRef operator[] (size_t index) {
    if (index < this->size()) return SafeRef(this->data() + index);
    return SafeRef(nullptr);
  }

  LenProxy length;

  template<typename ... Args>
  svector& operator=(Args&& ... args) {
    static_cast<vector<T>*>(this)->operator=(args...);
    //length.set(this);
    return *this;
  }
};

// while(cin >> string)
// class istream {
//    operator bool() {return ...}
//}

int main() { 
  svector<int> a(5,123);
  svector<int> b(a);
  svector<int> c;
  c=a;

  a.push_back(5);
  a.push_back(5);

  a.length=30;
  a.push_back(a.length);

  a[5] = 321;
  a[10] = 345345;
  a[50] = 345345;
  cout << a[5] << std::endl;
  cout << a[10] << std::endl;
  cout << a[50] << std::endl;


  c.length = 5;

  //special_printf("Hello\n");
  //special_printf("Hello %d\n", 123);
  
  std::cout << "Hello World!\n";

  for(auto&&i:a) cout << i << endl;
}
