// leda_impl.C
// ----------------------------------------------------------------
// COMP 290-001: Algorithm Library Design, Lutz Kettner, 01/11/2000
// Example for LEDA data structure implementations. The example
// is a simple ordered pair. It illustrates also how the type
// dependent comparison function is implemented as a virtual member
// function. Const-correctness is ignored here. Copying, assigning,
// and proper destruction of pairs is also ignored here.

#include <assert.h>

// Base class working on void* pointers. Can be precompiled and
// put in the library. For simplicity, it is implemented inline here.

class pair_impl {
    void* d_min;
    void* d_max;
protected:  // this class is only ment for derivation
    // to be implemented in derived class:
    virtual bool cmp( void* a, void* b) = 0; 
    // note, constructor doesn't work here instead of set() because
    // the virtual cmp function wouldn't be available (will be available
    // after derived class is constructed).
    void set( void* a, void* b) { 
	if ( cmp(a,b)) {
	    d_min = a;
	    d_max = b;
	} else {
	    d_min = b;
	    d_max = a;
	}
    }
    void* min() { return d_min; }
    void* max() { return d_max; }
};

// Derived class template. Knows the actual type and implements the
// comparison function. Does convert between type and void* pointers.
// Resides in header file. Almost all functions are usually inline 
// and short. Deals also with dynamic allocation and deletion of the
// items. Derivation is private, since derivation is only needed as
// an implementation technique to implement the comparison function 
// easily.

template <class T>
class pair : private pair_impl {
    virtual bool cmp( void* a, void* b) { 
	// use casts to T
	return * static_cast<T*>(a) < * static_cast<T*>(b);
    }
public:
    pair( const T& a, const T& b) { set( new T(a), new T(b)); }
    T& min() { return * static_cast<T*>( pair_impl::min()); }
    T& max() { return * static_cast<T*>( pair_impl::max()); }
};

int main() {
    pair<int> p(5, 8);
    assert( p.min() == 5);
    assert( p.max() == 8);
}

