#include #define DBG fprintf(stderr,"%d: %d\n",ts::myRank,__LINE__) struct Expr; typedef ts::TVar TExpr; struct Expr : private ts::TExtData { private: TExpr* terms; public: Expr () : terms(0) {}; void init (size_t s) { assert(!terms); terms = new TExpr[s]; extDataSize() = s * sizeof(TExpr); }; operator const TExpr* () const { return terms ? terms : (TExpr*)extData(); } operator TExpr* () { return terms ? terms : (TExpr*)extData(); } Expr (const Expr& e) : terms(0) { TExpr* p = *this; const TExpr* q = e; for (unsigned i = 0; i < e.getLength(); i++) new (p++) TExpr(*q++); } size_t getLength () const { return extDataSize() / sizeof(TExpr); } TExpr& operator[] (int i) { return ((TExpr *)*this)[i]; } ~Expr () { if (terms) delete[] terms; else { TExpr* p = *this; for (unsigned i = 0; i < getLength(); i++) p++->~TExpr(); } } }; tfun int depth (TExpr e) { Expr& x = (Expr&) e; if (x.getLength() != 2) return 1; tval int x0 = depth(x[0]); tval int x1 = depth(x[1]); return std::max((int)x0, (int)x1) + 1; } tfun int main(int argc, char *argv[]) { TExpr e; ((Expr&)e).init(0); for (int i = 0; i < (argc > 1 ? atoi(argv[1]) : 10); i++) { TExpr z; Expr& x = (Expr&) z; x.init(2); x[0] = e; x[1] = e; e = z; } printf("%d\n", (int)depth(e)); return 0; }