#ifndef CPP_EXEC_SHARE_H
#define CPP_EXEC_SHARE_H

// Eine Klasse zur Verwaltung mehrfach benutzter Resourcen
//
// Kopiert man Instanzen, die eine Resource alloziieren und im Destruktor
// freigeben, so ist die Resource mehrfach referenziert und darf erst
// durch den letzten Destruktor freigegeben werden. Dabei hilft die Klasse
// ShareC. Am einfachsten erbt man von dieser Klasse. Allerdings muß diese
// Klasse selbst etwas dynamischen Speicher alloziieren, die Konstruktion
// kann also fehlschlagen, dann wird die Ausnahme MemoryX ausgeworfen. Mit
// only() kann man herausfinden, ob die Instanz die einzige Referenz hält.
//
// Der Destruktor muß mit only() testen, ob diese Instanz die letzte
// letzte Referenz enthält: liefert only() das Ergebnis TRUE, so muß
// die Resource freigegeben werden.
//
// Der Zuweisungsoperator funktioniert entsprechend: Zuerst muß mit only()
// getestet werden, ob die Resource freizugeben ist, danach wird der
// Zuweisungsoperator der Klasse ShareC aufgerufen. Diesem folgen die
// weiteren Zuweisungen, überlichweise zumindest die Zuweisung der Referenz
// auf die Resource.
//
// Die Klasse ShareManualC erfüllt eine ähnliche Aufgabe, hier muß man jedoch
// die Referenzierung (reference()) und Dereferenzierung (dereference())
// selbst vornehmen. Der Gebrauch dieser Klasse ist dann sinnvoll, wenn
// eine Resource nicht direkt an eine Klasse gebunden ist, d.h. nicht
// unbedingt bei jedem Kopieren oder Zuweisen zusätzlich neu referenziert
// wird.
//
// Destruktor und Zuweisungsoperator funktionieren der Klasse ShareC
// entsprechend. Nur die Referenzierungen müssen "zu Fuß" vorgenommen
// werden. Normalerweise sollte es nicht passieren, daß im "letzten"
// Destruktor (bzw. Zuweisungsoperator) die Methode only() das Ergebnis
// FALSE liefert und damit die Resource nicht freigegeben wird, obwohl die
// letzte Referenz darauf verloren geht. Dies ist normalerweise ein
// Ungleichgewicht in der Benutzung von reference() und dereference().
//
// Autor: Jochen Becher
//
// Historie:
// Version 1.0 am 25. Juni 94

#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif

#ifndef CPP_EXCEPTIONS_EXCEPTIONS_H
#include <classes/exceptions/exceptions.h>
#endif

class ShareC {
public:
	ShareC() throw (MemoryX);
	ShareC(const ShareC &);
	~ShareC();
	ShareC &operator = (const ShareC &);
	BOOL only() const;
private:
	ULONG *counter;
};

class ShareManualC : private ShareC {
public:
	ShareManualC() throw (MemoryX);
	ShareManualC(const ShareManualC &);
	~ShareManualC();
	ShareManualC &operator = (const ShareManualC &);
	VOID reference();
	VOID dereference();
	BOOL only() const;
private:
	ULONG *references;
};

#endif
