#if defined(_Windows) || defined(_MSC_VER) || defined (__GNUC__) #define STRICT #include #endif #include #define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING #define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE #include #include #include #include #include //------------------------------------------------------------------------------ #define UINT32 unsigned long #define STRING std::string //------------------------------------------------------------------------------ // choose one //#define VERSION01 //#define VERSION02 //#define VERSION03 //#define VERSION04 //------------------------------------------------------------------------------ template class tCanMap { protected: mutable MAP _mpMap; // map mutable SC1 *_scNme; // sorting criteria name ... have to init from derived class mutable SC2 *_scDat; // sorting criteria name ... have to init from derived class public: tCanMap (); MAP &getmap () const; UINT32 setmapelm (ELM val); #if defined (VERSION01) || defined (VERSION02) const ELM *getmapelm (STRING stNme) const; const ELM *getmapelm (UINT32 uiDat) const; #endif }; template tCanMap::tCanMap() { this->_scNme = NULL; this->_scDat = NULL; } template MAP &tCanMap::getmap() const { return this->_mpMap; } template UINT32 tCanMap::setmapelm(ELM val) { if (this!=NULL) { this->_mpMap.insert(val); return 0; } return 1; } #if defined (VERSION01) || defined (VERSION02) template const ELM *tCanMap::getmapelm(STRING stNme) const { try { IT1 itr = this->_mpMap.template get<0>().find(stNme); if ( itr != this->_mpMap.template get<0>().end() ) { return &(*itr); } } catch(...) {} return NULL; } template const ELM *tCanMap::getmapelm(UINT32 uiDat) const { try { IT2 itr = this->_mpMap.template get<1>().find(uiDat); if ( itr != this->_mpMap.template get<1>().end() ) { return &(*itr); } } catch(...) {} return NULL; } #endif //------------------------------------------------------------------------------ class cClass00 { private: STRING _nme; UINT32 _dat; public: cClass00() {} cClass00(STRING nme, UINT32 dat) { this->_nme=nme; this->_dat=dat; } STRING getnme () const { return this->_nme; } UINT32 getdat () const { return this->_dat; } }; typedef boost::multi_index_container < cClass00, boost::multi_index::indexed_by < boost::multi_index::hashed_unique < BOOST_MULTI_INDEX_CONST_MEM_FUN(cClass00,STRING,getnme) >, boost::multi_index::ordered_unique < BOOST_MULTI_INDEX_CONST_MEM_FUN(cClass00,UINT32,getdat) > > > mClass00; typedef mClass00::nth_index<0>::type mClass00ByNme; typedef mClass00ByNme::iterator mClass00ByNmeItr; typedef mClass00::nth_index<1>::type mClass00ByDat; typedef mClass00ByDat::iterator mClass00ByDatItr; //------------------------------------------------------------------------------ class cClass01 : public tCanMap { private: STRING _nme; UINT32 _dat; typedef tCanMap super; public: cClass01() {} cClass01(STRING nme, UINT32 dat) { this->_nme=nme; this->_dat=dat; this->_scNme = &(this->_mpMap.get<0>()); this->_scDat = &(this->_mpMap.get<1>()); } cClass01(const cClass01& x): super(x), _nme(x._nme), _dat(x._dat) { this->_scNme = &(this->_mpMap.get<0>()); this->_scDat = &(this->_mpMap.get<1>()); } cClass01& operator=(const cClass01& x) { super::operator=(x); this->_nme=x._nme; this->_dat=x._dat; this->_scNme = &(this->_mpMap.get<0>()); this->_scDat = &(this->_mpMap.get<1>()); return *this;} STRING getnme() const { return this->_nme; } UINT32 getdat() const { return this->_dat; } #if defined (VERSION03) || defined (VERSION04) const cClass00 *getmapelm (STRING stNme) const { try { if ( this!=NULL ) { mClass00ByNmeItr itr = this->_mpMap.get<0>().find(stNme); if ( itr != this->_mpMap.get<0>().end() ) { return &(*itr); } } } catch(...) {} return NULL; } const cClass00 *getmapelm (UINT32 uiDat) const { try { if ( this!=NULL ) { mClass00ByDatItr itr = this->_mpMap.get<1>().find(uiDat); if ( itr != this->_mpMap.get<1>().end() ) { return &(*itr); } } } catch(...) {} return NULL; } #endif }; typedef boost::multi_index_container < cClass01, boost::multi_index::indexed_by < boost::multi_index::hashed_unique < BOOST_MULTI_INDEX_CONST_MEM_FUN(cClass01,STRING,getnme) >, boost::multi_index::ordered_unique < BOOST_MULTI_INDEX_CONST_MEM_FUN(cClass01,UINT32,getdat) > > > mClass01; typedef mClass01::nth_index<0>::type mClass01ByNme; typedef mClass01ByNme::iterator mClass01ByNmeItr; typedef mClass01::nth_index<1>::type mClass01ByDat; typedef mClass01ByDat::iterator mClass01ByDatItr; //------------------------------------------------------------------------------ class cClass02 : public tCanMap { typedef tCanMap super; public: cClass02() { this->_scNme = &(this->_mpMap.get<0>()); this->_scDat = &(this->_mpMap.get<1>()); } cClass02(const cClass02& x): super(x) { this->_scNme = &(this->_mpMap.get<0>()); this->_scDat = &(this->_mpMap.get<1>()); } cClass02& operator=(const cClass02& x) { super::operator=(x); this->_scNme = &(this->_mpMap.get<0>()); this->_scDat = &(this->_mpMap.get<1>()); return *this;} #if defined (VERSION03) || defined (VERSION04) const cClass01 *getmapelm (STRING stNme) const { try { if ( this!=NULL ) { mClass01ByNmeItr itr = this->_mpMap.get<0>().find(stNme); if ( itr != this->_mpMap.get<0>().end() ) { return &(*itr); } } } catch(...) {} return NULL; } const cClass01 *getmapelm (UINT32 uiDat) const { try { if ( this!=NULL ) { mClass01ByDatItr itr = this->_mpMap.get<1>().find(uiDat); if ( itr != this->_mpMap.get<1>().end() ) { return &(*itr); } } } catch(...) {} return NULL; } #endif }; //------------------------------------------------------------------------------ int main(void) { #if defined (VERSION01) || defined (VERSION03) // works fine in any case cClass00 objClass00_01 = cClass00( "elm00_01", 1 ); cClass00 objClass00_02 = cClass00( "elm00_02", 2 ); cClass00 objClass00_03 = cClass00( "elm00_03", 3 ); cClass00 objClass00_04 = cClass00( "elm00_04", 4 ); cClass01 objClass01_01 = cClass01( "elm01_01", 11 ); cClass01 objClass01_02 = cClass01( "elm01_02", 12 ); objClass01_01.setmapelm( objClass00_01 ); objClass01_01.setmapelm( objClass00_02 ); objClass01_02.setmapelm( objClass00_03 ); objClass01_02.setmapelm( objClass00_04 ); cClass02 *ptrClass02_01 = new cClass02(); ptrClass02_01->setmapelm( objClass01_01 ); ptrClass02_01->setmapelm( objClass01_02 ); printf("START\n"); printf("\n"); printf( "1. try: %02d\n", ptrClass02_01->getmapelm("elm01_01")->getdat() ); printf( "2. try: %02d\n", ptrClass02_01->getmapelm("elm01_02")->getdat() ); printf("\n"); printf( "3. try: %02d\n", ptrClass02_01->getmapelm("elm01_01")->getmapelm("elm00_01")->getdat() ); printf( "4. try: %02d\n", ptrClass02_01->getmapelm("elm01_02")->getmapelm("elm00_04")->getdat() ); printf("\n"); printf( "5. try: %s\n", ptrClass02_01->getmapelm("elm01_01")->getmapelm(2)->getnme().c_str() ); printf( "6. try: %s\n", ptrClass02_01->getmapelm("elm01_02")->getmapelm(3)->getnme().c_str() ); printf("\n"); printf("DONE\n"); #elif defined (VERSION02) || defined (VERSION04) // run into segvault if object become overwritten OR // object for filling multi_index is only a local variable of a filling function cClass02 *ptrClass02 = new cClass02(); cClass01 objClass01; cClass00 objClass00; objClass01 = cClass01("elm01_01", 11); objClass00 = cClass00("elm00_01", 1); objClass01.setmapelm(objClass00); objClass00 = cClass00("elm00_02", 2); objClass01.setmapelm(objClass00); ptrClass02->setmapelm(objClass01); // insert objClass01 objClass01 = cClass01("elm01_02", 12); objClass00 = cClass00("elm00_03", 4); objClass01.setmapelm(objClass00); objClass00 = cClass00("elm00_04", 3); objClass01.setmapelm(objClass00); ptrClass02->setmapelm(objClass01); // inserted object different than above printf("START\n"); printf( "dat = %d\n", ptrClass02->getmapelm("elm01_01")->getdat() ); // seg_vault // printf( "dat = %d\n", ptrClass02->getmapelm("elm01_02")->getdat() ); // works fine printf("DONE\n"); #endif }