#include <iostream>
#include <vector>

template <typename T>
class svector : public std::vector<T> {
  class safe_ref{
    T *p;
    public:
    safe_ref(T *p) : p(p) {}

    safe_ref& operator=(const T & t)  {
      if(p)
        *p = t;
      return *this;
    }

    operator T() {
      if(p) {
        return *p;
      }
      else {
        return T();
      }

    }
  };

  // svector[ vector<T> , ...., length, ..... ]
  // ^                          ^--this
  //offsetof(parAB, b) 
  class length_proxy{
    svector* parent() {
      return reinterpret_cast<svector*>(reinterpret_cast<char*>(this)-offsetof(svector, length));
    }
    public:
    length_proxy& operator=(size_t length){
      parent()->resize(length);
      return *this;
    }

    operator size_t() {
      return parent()->size();
    }
  };
  public:
  //svector(size_t size, const T& val) : std::vector<T>(size, val) { }
  
  //template< class... Args >
  //void emplace_back( Args&&... args );
  template<typename ... P>
  svector(P&&... param) : std::vector<T>(param...) /*, length(this)*/{}

  template<typename ... P>
  svector& operator=(P&&... param) {
    static_cast<std::vector<T>*>(this)->operator=(param...);
    return *this;
  }

  safe_ref operator[](size_t i) {
      if(i >= this->size()) {
        return safe_ref(nullptr);
      }
      else {
        return safe_ref(this->data() + i);
        //return safe_ref(&(static_cast<std::vector<T>*>(this)->operator[](i)));
      }
  }

  length_proxy length;
};

int main() {
  svector<int> a(5,123);
  svector<int> b(a);
  svector<int> c;
  c=a;
  a.length = 3;
  a[1]=42;
  a[5]=111;
  a.push_back(a.length);
  std::cout << a[1] << std::endl;
  std::cout << a[5] << std::endl;
  a[0] = a[1]+a[5];
  c.length=30;
  for(auto&&i:a) std::cout << i << std::endl;
  std::cout << "----" << std::endl;
  for(auto&&i:c) std::cout << i << std::endl;
  return 0;
}
