//Relations.h
#ifndef _RELATIONS_H
#define _RELATIONS_H
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
// OneOne relationship template class
template < class First, class Second,
class CompareFirst = less<First>,
class CompareSecond = less<Second> >
class OneOne
{
typedef map <First, Second, CompareFirst> FirstSecond;
typedef map <Second, First, CompareSecond>SecondFirst;
FirstSecond _FirstSecond;
SecondFirst _SecondFirst;
public:
// Insert a pair of elements
bool insert(const First& f, const Second& s);
// Remove a pair with this First if it was inserted
bool removeByFirst(const First& f);
// Remove a pair with this Second if it was inserted
bool removeBySecond(const Second& s);
// Return the Second item for this First
// or NULL if it doesn't exist
Second * getSecond(const First& f);
// Return the First item for this Second
// or NULL if it doesn't exist
First * getFirst(const Second& s);
void clear(); // Clear this relationship
// Define iterator for this relationship
typedef FirstSecond::iterator iterator;
iterator begin() { return _FirstSecond.begin(); }
iterator end() { return _FirstSecond.end(); }
};
//--------------------------------------------------------------
// OneMany relationship template class
template <class One, class Many,
class CompareOne = less<One>,
class CompareMany= less<Many> >
class OneMany
{
//maps One to several Many
typedef multimap <One, Many, CompareOne> OneManyMap;
OneManyMap _OneManyMap;
//maps each Many to its One
typedef map <Many, One, CompareMany> ManyOneMap;
ManyOneMap _ManyOneMap;
public:
// Insert this One Many pair to this relationship
// if it is not already there
bool insert(const One& o, const Many& m);
// Remove this Many if it was inserted
bool removeByMany(const Many& m);
// Remove this One if it was inserted
bool removeByOne(const One& o);
// Return the One for this Many
// or NULL if it doesn't exist
One* getOne(const Many& m){
// Nested iterator class for Many
class ManysIterator{...omitted...};
typedef ManysIterator <One, Many> iterator;
// Nest const iterator class for Many
class ConstManysIterator
: public ManysIterator{...omitted...};
typedef ConstManysIterator <One, Many> const_iterator;
// The begin and end iterators for this One
iterator begin(const One& o);
iterator end(const One& o);
// The const begin and end iterators for this One
const_iterator begin(const One& o) const;
const_iterator end(const One& o) const;
void clear(); // Clear this relationship
};
//--------------------------------------------------------------
// triple struct used by ManyMany relationship
template <class T1, class T2, class T3>
struct triple : public pair<T1, T2>{
triple(const T1& x, const T2& y, const T3& z)
: pair<T1, T2>(x, y), third(z){}
T3 third;
};
template <class T1, class T2, class T3>
inline triple<T1, T2, T3>
make_triple(const T1& x, const T2& y, const T3& z){
return triple<T1, T2, T3>(x, y, z);
}
// ValToType struct to determine type; used at compile time
template <class T1, class T2, class T3>
struct ValToType{ typedef triple <T1, T2, T3> type; };
// Partial template specialization of ValToType class
template <class T1, class T2>
struct ValToType<T1, T2, void>{ typedef pair <T1, T2> type; };
ManyMany relationship template class
template <class Many1, class Many2,
class CompareMany1 = less<Many1>,
class CompareMany2 = less<Many2>,
class Rel = void>
class ManyMany{
typedef ValToType< Many1, Many2, Rel >::type Relation;
typedef vector<Relation> Relations;
Relations _Relations;
typedef multimap <Many1, Relation, CompareMany1> One1Many2Map;
One1Many2Map _One1Many2Map;
typedef multimap <Many2, Relation, CompareMany2> One2Many1Map;
One2Many1Map _One2Many1Map;
public:
// Insert this Many1 Many2 pair to the relationship
bool insert(const Many1& m1, const Many2& m2){
Relation rel(m1, m2);
_Relations.push_back(rel);
_One1Many2Map.insert( make_pair (m1, rel) );
_One2Many1Map.insert( make_pair (m2, rel) );
return true;
}
// Insert this Many1 Many2 Rel triple to the relationship
bool insert(const Many1& m1, const Many2& m2, const Rel& r);
// Remove this Many1
bool removeByMany1(const Many1& m1);
// Remove this Many2
bool removeByMany2(const Many2& m2);
Nested functor struct used to find relations
struct eqRel{...omitted...};
// Remove this Many1 Many2 pair
bool remove(const Many1& m1, const Many2& m2);
// Return the Link Attribute for this pair of Many1 Many2
// or NULL if not found
const Rel* getAttribute(const Many1& m1, const Many2& m2);
//--------------------------------------------------
// Nested iterator class for iterating over Many1s
class Manys1Iterator{
protected:
typedef One2Many1Map::iterator OMI;
OMI _mi;
typedef bidirectional_iterator_tag iterator_category;
typedef Manys1Iterator<Many1, Many2> self;
public:
Manys1Iterator(OMI mi = OMI()) : _mi(mi){}
...
self& operator++() {
_mi++;
return *this;
}
...
};
//--------------------------------------------------
class Manys2Iterator{...omitted...};
// Iterator types to iterate through Many1's and Many2's
// respectively
typedef Manys1Iterator <Many1, Many2> iterator1;
typedef Manys2Iterator <Many1, Many2> iterator2;
// The begin and end iterators for this Many2
iterator1 begin(const Many2 & m2)
{ return iterator1(_One2Many1Map.lower_bound(m2)); }
iterator1 end(const Many2 & m2)
{ return iterator1(_One2Many1Map.upper_bound(m2)); }
// The begin and end iterators for this Many1
iterator2 begin(const Many1 & m1)
{ return iterator2(_One1Many2Map.lower_bound(m1)); }
iterator2 end(const Many1 & m1)
{ return iterator2(_One1Many2Map.upper_bound(m1)); }
void clear(){ // Clear this relationship
_One1Many2Map.clear();
_One2Many1Map.clear();
_Relations.clear();
}
};
#endif
End of Listing