Listing 1: Partial listing of Relations.h — association class definitions

//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 —