File:  [parser3project] / parser3 / src / include / pa_pool.h
Revision 1.28: download - view: text, annotated - select for diffs - revision graph
Sun Mar 11 08:16:32 2001 UTC (25 years, 4 months ago) by paf
Branches: MAIN
CVS tags: HEAD
headers updated

/*
	Parser
	Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
	Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)

	$Id: pa_pool.h,v 1.28 2001/03/11 08:16:32 paf Exp $
*/

#ifndef PA_POOL_H
#define PA_POOL_H

#include <stddef.h>

class Exception;
class Temp_exception;

class Pool {
	friend Temp_exception;
public:

	Pool() : fexception(0) {}
	~Pool() {}

	Exception& exception() const { return *fexception; }

	void *malloc(size_t size) {
		return check(real_malloc(size), size);
	}
	void *calloc(size_t size) {
		return check(real_calloc(size), size);
	}

private: // implementation defined

    void *real_malloc(size_t size);
    void *real_calloc(size_t size);

private: 

	// checks whether mem allocated OK. throws exception otherwise
	void *check(void *ptr, size_t size) {
		if(ptr)
			return ptr;

		fail(size);

		// never reached
		return 0;
	}
	// throws proper exception
	void fail(size_t size) const;

protected: // exception handling

	// exception replacement mechanism is 'protected' from direct usage
	// Temp_exception_change object enforces paired set/restore
	Exception *set_exception(Exception *e){
		Exception *r=fexception;
		fexception=e;
		return r;
	}
	void restore_exception(Exception *e) {
		fexception=e;
	}

private:

	// current request's exception object
	Exception *fexception;

private: //disabled

	// Pool(const Pool&) {}
	Pool& operator = (const Pool&) { return *this; }
};

class Pooled {
	// the pool i'm allocated on
	Pool& fpool;
public:
	
	static void *operator new(size_t size, Pool& apool) { 
		return apool.malloc(size);
	}

	Pooled(Pool& apool) : fpool(apool) {
	}

	Pool& pool() const { return fpool; }

	void *malloc(size_t size) const { return fpool.malloc(size); }
	void *calloc(size_t size) const { return fpool.calloc(size); }
	Exception& exception() const { return fpool.exception(); }
};
#define NEW new(pool())

class Temp_exception {
	Pool pool;
	Exception *saved_exception;
public:
	Temp_exception(Pool& apool, Exception& exception) : 
		pool(apool),
		saved_exception(apool.set_exception(&exception)) {
	}
	~Temp_exception() { 
		pool.restore_exception(saved_exception); 
	}
};

#define TRY \
	{ \
		Exception temp_exception; \
		Temp_exception le(pool(), temp_exception); \
		if(setjmp(temp_exception.mark)==0)

#define THROW exception()._throw
#define POOL_THROW pool.exception()._throw
#define CATCH(e) \
		else{ \
			Exception& e=temp_exception;

#define END_CATCH \
		} \
	}
// usage:
//   TRY { ...; if(?) RAISE(?); ...; } CATCH(e) { catch-code e.comment() } END_CATCH

#endif

E-mail: