/*************************************************************************** * Copyright (C) 2005 by Jeff Ferr * * root@sat * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "jgc.h" #ifndef _SMGC_POOR_STL #include #include #else #include #include #endif using namespace jcommon; using namespace std; inline static void do_nothing() { } //#define opt_collect jcommon::collect #define opt_collect do_nothing templatestruct bst { typedef gc_ptr > subtree; typedef const_gc_ptr > const_subtree; //template //friend class bst; subtree left, right; T val; bool empty; bst(): empty(true) { } bst(const bst &b): empty(false), val(b.val), left(b.left), right(b.right) { } templateexplicit bst(const U &v): val(v), empty(false) { } templatebst& operator =(const U &v) { if(empty) { val = v; empty = false; } else if(v < val) { if(!left) left = new(GC) bst; *left = v; } else if(val < v) { if(!right) right = new(GC) bst; *right = v; } else { //cerr << "Duplicate bst node!" << endl; if(!right) right = new(GC) bst; *right = v; } return *this; } const T& operator *() const { return val; } const T* operator ->() const { return &val; } T& operator *() { return val; } T* operator ->() { return &val; } }; template ostream& operator <<(ostream &o, bst &b) { o << "("; if(b.left) o << *(b.left) << " "; if(b.val) o << b.val; if(b.right) o << " " << *(b.right); o << ")"; return o; } templategc_ptr >& find(gc_ptr >& tree, const U &v) { static gc_ptr > nothing; if(!tree) return nothing; if(!(tree->empty) && (tree->val == v)) return tree; else if(tree->left && (v < tree->val)) return find(tree->left, v); else if(tree->right && (tree->val < v)) return find(tree->right, v); else return nothing; } class base1 { public: virtual ~base1() { } protected: int b1; }; class base2 { public: virtual ~base2() { } protected: int b2; }; class inherits: public base1, public base2 { public: virtual ~inherits() {} public: inherits() { b1 = 1; b2 =2; } }; void testmulti() { try { cout << "making base1(inherits)" << endl; gc_ptr b1(new(GC) inherits); cout << "making base2(inherits)" << endl; gc_ptr b2(new(GC) inherits); gc_ptr inh(new(GC) inherits); b2 = inh; const gc_ptr &bb = b2; inh = dynamic_cast_gc_ptr(bb); cout << "inherits done" << endl; } catch(...) { cerr << "Invalid use of multiinheritance" << endl; } } struct cnt { static unsigned count; cnt() { ++count; cout << " (+)" << cnt::count << flush; } cnt(const cnt&) { ++count; cout << " (*)" << cnt::count << flush; } virtual ~cnt() { --count; cout << " (-)" << cnt::count << flush; } }; unsigned cnt::count = 0; const gc_ptr pass(const gc_ptr p) { return p; } gc_ptr multipass(gc_ptr p) { return pass(pass(pass(p))); } const cnt pass(const cnt p) { return p; } cnt multipass(cnt p) { return pass(pass(pass(p))); } void testcompiler() { cout << "Testing compiler validity..." << endl; { const cnt c = cnt(); const cnt r = multipass(c); } cout << endl; cout << "cnt::count = " << cnt::count << endl; if(cnt::count) { cout << "your compiler (probably gcc 3.2.x) has a bug!" << endl; return; } { const_gc_ptr r = multipass(new(GC) int(13)); } } class contain { gc_ptr a; public: contain() { a = new(GC) cnt(); } ~contain() { cout << "~contain" << endl; } void check() { cout << "check" << endl; } }; void testcontain() { cout << "Testing containers" << endl; cout << endl; cout << "0. cnt::count = " << cnt::count << endl; { gc_ptr c = new(GC) contain(); cout << endl; cout << "1. cnt::count = " << cnt::count << endl; cout << endl; cout << "collecting..." << endl; collect(); cout << endl; cout << "2. cnt::count = " << cnt::count << endl; c->check(); } cout << endl; cout << "collecting..." << endl; collect(); cout << endl; cout << "3. cnt::count = " << cnt::count << endl; } void subfun() { size_t i, j=0; gc_arr > arr(new(GC) gc_ptr[200000]); //gc_ptr arr[20000]; gc_arr > wk(new(GC) const_wk_ptr[400000]); for(i=0; i<200000; i++) { arr[i] = new(GC) int(i); wk[j++] = arr[i]; } opt_collect(); cout << "arr(1):" << flush; for(i=0; i<200000; i++) { cout << " " << *(arr[i]);// << flush; if(*(arr[i]) != (int)i) { cout << "Error(1)!" << endl; exit(20); } } cout << endl; opt_collect(); for(i=0; i<200000; i++) { arr[i] = new(GC) int(-i); wk[j++] = arr[i]; } jcommon::collect(); cout << "arr(2):" << flush; for(i=0; i<200000; i++) { cout << " " << *(arr[i]);// << flush; if(*(arr[i]) != (int)-i) { cout << "Error(2)!" << endl; exit(20); } } cout << endl; j=0; cout << "wk:" << flush; for(i=0; i<400000; i++) { const_gc_ptr w = wk[i].get(); if(w) { cout << " " << *w;// << flush; j++; } else { cout << " NULL"; } } cout << endl; } int main(int argc, char *argv[]) { //jcommon::set_threshold(0); testcontain(); gc_ptr a,b,c,d; size_t i,j; int v=0, w=0; if(argc>1) j = atoi(argv[1]); else j = 27890; testmulti(); testcompiler(); subfun(); opt_collect(); srand(123456); a = new(GC) int(1); b = new(GC) int(2); c = new(GC) int(3); d = a; gc_ptr e(b); gc_ptr f(new(GC) int(3)); cout << "abcdef: " << *a << *b << *c << *d << *e << *f << endl; gc_ptr > tree(new(GC) bst); cout << "data:"; for(i=0; i<128; ++i) { v = rand(); *tree = v; cout << " " << v; if(i == 100) w = v; } cout << endl; cout << "tree: " << *tree << endl; opt_collect(); tree = find(tree, w); cout << "tree[w]: " << *tree << endl; opt_collect(); cout << "data(2):"; for(i=0; i<163840; ++i) { v = rand(); *tree = v; cout << " " << i << ":" << v << flush; if(i == j) w = v; } cout << endl; cout << "tree(2): " << *tree << endl; tree = find(tree, w); cout << "tree[w](2): " << *tree << endl; cout << jcommon::get_threshold() << endl; cout << jcommon::get_dynamic_threshold() << endl; return 0; }