Listing 1: nwayset.h

#ifndef AIW_NWAYSET_H_INCLUDED
#define AIW_NWAYSET_H_INCLUDED
#include <list>
#include <set>
#ifndef STD_NAMESPACE_USED
using namespace std;
#define STD_NAMESPACE_USED
#endif

template<class T, class A = allocator<T> > class nwayset 
{
    public:
        //forward decls
        class CCompareHelper;
        class CDataListIterator;
                
        //some typedefs
        typedef bool (*TFncCompare)(const T &, const T &);
        typedef list<T, A> TDataList;
        typedef multiset<CDataListIterator,CCompareHelper> TIndex;
        typedef TIndex index;
        typedef list<TIndex> TIndexList;
                        
        //////////////////////
        class CCompareHelper : public binary_function
           <CDataListIterator, CDataListIterator, bool>
        {
            public:
                inline CCompareHelper() : m_fncCompare(NULL) {};
                inline CCompareHelper(TFncCompare fncCompare)
                {m_fncCompare=fncCompare;};
                inline bool operator()(CDataListIterator x, 
                    CDataListIterator y) const
                    { return m_fncCompare(*x, *y);};

            protected:
                mutable TFncCompare m_fncCompare;
        };

        //////////////////////
        class CDataListIterator : public TDataList::iterator
        {
            public:
                inline CDataListIterator(TDataList::iterator it)
                {
                    m_p=NULL;
                    *((TDataList::iterator *)(this))=it;
                }

                inline CDataListIterator(const T &obj) 
                { m_p=(T *)&obj;}

                inline T &operator*(void)
                    { return m_p ? *m_p : 
                         *(*((TDataList::iterator *)this));}

                inline const T &operator*(void) const
                    { return m_p ? *m_p : 
                         *(*((TDataList::iterator *)this));}

            private:
                T *m_p;
        };
                
        //////////////////////
        typedef class CConstIterator : 
            public TIndex::const_iterator
        {
            public:
                inline CConstIterator(TIndex::const_iterator it)
                {
                    m_p=NULL;
                    *((TIndex::const_iterator *)(this))=it;
                }

                inline CConstIterator(const T &obj) { m_p=&obj; }

                inline const T &operator*(void) const
                { return m_p ? *m_p : 
                      *(*(*((TIndex::const_iterator *)(this))));}
            private:
                const T *m_p;

        } const_iterator;

        //////////////////////
        typedef class CIterator : public TIndex::iterator
        {
            public:
                inline CIterator(TIndex::iterator it)
                {
                    m_p=NULL;
                    *((TIndex::iterator *)(this))=it;
                }

                inline CIterator(T &obj) {m_p=&obj;}
                
                inline T &operator*(void)
                {return m_p ? *m_p : 
                    *(*(*((TIndex::iterator *)(this))));}

            private:
                T *m_p;

        } iterator;
        
        //////////////////////
        //index related functions
        typedef TIndexList::iterator index_iterator;
        typedef TIndexList::const_iterator const_index_iterator;

        ////add a new index
        index_iterator index_insert(TFncCompare fncCompare)
        {
            TIndexList::iterator it =
                m_lIndexes.insert(m_lIndexes.end(), 
                    TIndex(CCompareHelper(fncCompare)));
            TIndex &obj=(*it);
            for(TDataList::iterator itData=m_lData.begin();
                itData!=m_lData.end();
                itData++)
                { obj.insert(itData); }

            return it;
        }

        ////begin iterator for indexes
        inline index_iterator index_begin(void) 
        { return m_lIndexes.begin(); }
        inline const_index_iterator index_begin(void) const 
        { return m_lIndexes.begin(); }

        ////end iterator for indexes
        inline index_iterator index_end(void) 
        { return m_lIndexes.end();}
        inline const_index_iterator index_end(void) const 
        {return m_lIndexes.end(); }

        ////remove an index
        inline void index_erase(index_iterator it) 
        { m_lIndexes.erase(it);}

        //nwayset global related functions
        ////get size of set
        inline int size(void) const {return m_lData.size();};

        /////inserts an item
        inline bool insert(const T &x)
        {
            TDataList::iterator it =
                m_lData.insert(m_lData.end(), x);
            for(TIndexList::iterator itIndexes=m_lIndexes.begin();
                itIndexes!=m_lIndexes.end();
                itIndexes++)
                { (*itIndexes).insert(it); }
            return true;
        }

        ////erase an item
        void erase(CIterator it)
        {
            T &obj=*it;
            TDataList::iterator itItem=*((TIndex::iterator)it);
            for(TIndexList::iterator itIndex=m_lIndexes.begin();
                itIndex!=m_lIndexes.end();
                itIndex++)
            {
                TIndex &objIndex=(*itIndex);
                for(CIterator itData=objIndex.find(obj);
                    itData!=objIndex.end();
                    itData++)
                {
                    TDataList::iterator itEntry =
                        *((TIndex::iterator)itData);
                    if(itEntry==itItem)
                    {
                        objIndex.erase(itData);
                        break;
                    }
                }
            }

            m_lData.erase(itItem);
        }

        ////search all indexes for an item
        CConstIterator find(const T &obj) const
        {
            for(TIndexList::const_iterator itIndex =
                    m_lIndexes.begin();
                itIndex!=m_lIndexes.end();
                itIndex++)
            {
                const TIndex &objIndex=(*itIndex);
                CConstIterator itResult(objIndex.find(obj));
                if(itResult!=objIndex.end())
                    return itResult;
            }

            return end();
        }

        ////search all indexes for an item
        CIterator find(const T &obj)
        {
            for(TIndexList::iterator itIndex=m_lIndexes.begin();
                itIndex!=m_lIndexes.end();
                itIndex++)
            {
                TIndex &objIndex=(*itIndex);
                CIterator itResult(objIndex.find(obj));
                if(itResult!=objIndex.end())
                    return itResult;
            }

            return end();
        }

        ////end to designate find failure
        CConstIterator end(void) const 
        { return (*m_lIndexes.begin()).end();}
        CIterator end(void) {return (*m_lIndexes.begin()).end();}

    protected:
        TDataList m_lData;
        TIndexList m_lIndexes;
};
#endif