#pragma once #include #include "chemelem.h" #include "mindbtypes.h" namespace geoworld { class MineralsDB : public IMineralsDatabase { private: typedef std::map< std::string, mars::ptr< MineralClass > > ClassesMap; public: typedef std::set< mars::ptr< MineralClass > > ClassesSet; class Ex : public std::exception { private: const char * _message; public: Ex (const char * szMsg) : _message(szMsg) {} virtual const char * what() const noexcept { return this->_message; } }; template< typename MAP > class MapIteratorWrapper : public std::iterator < std::input_iterator_tag, typename MAP::value_type > { private: typename MAP::const_iterator _i; public: MapIteratorWrapper (const typename MAP::const_iterator & i) : _i (i) {} inline MapIteratorWrapper & operator ++ () { ++_i; return *this; } inline MapIteratorWrapper & operator ++ (int) { MapIteratorWrapper old = *this; _i++; return old; } inline const typename MAP::value_type & operator * () const { return *_i; } inline const typename MAP::value_type & operator -> () const { return *_i; } }; typedef MapIteratorWrapper< ClassesMap > classes_const_iterator; class GenesisMineralMapping { public: MineralReference context; mars::ptr< MineralDef > mineral; MineralDef::GenesisList::const_iterator genesis; GenesisMineralMapping(const MineralReference & ctx, const mars::ptr< MineralDef > & pMin, const MineralDef::GenesisList::const_iterator & iGen) : context(ctx), mineral(pMin), genesis(iGen) {} inline bool operator < (const GenesisMineralMapping & other) const { return mineral < other.mineral || (mineral == other.mineral && context < other.context) || // TODO: Check use of MineralDef::GenesisList::const_iterator::_Ptr (mineral == other.mineral && context == other.context && &genesis < &other.genesis); } }; typedef std::set< GenesisMineralMapping > PetrogenyMineralSet; class GenesisClassMapping { public: mars::ptr< MineralDef > mineral; MineralDef::GenesisList::const_iterator genesis; GenesisClassMapping(const mars::ptr< MineralDef > & mineral, const MineralDef::GenesisList::const_iterator iGen) : mineral(mineral), genesis(iGen) {} inline bool operator < (const GenesisClassMapping & other) const { return mineral < other.mineral || (mineral == other.mineral && &genesis < &genesis); } }; typedef std::set< GenesisClassMapping > PetrogenyClassSet; class ClassesSetFacade { private: const ClassesSet & _classset; public: ClassesSetFacade (const ClassesSet & classes) : _classset (classes) {} inline ClassesSet::const_iterator begin() const { return _classset.begin(); } inline ClassesSet::const_iterator end() const { return _classset.end(); } }; class PetrogenyMineralSetFacade { private: const PetrogenyMineralSet & _petroset; public: PetrogenyMineralSetFacade (const PetrogenyMineralSet & petroset) : _petroset(petroset) {} inline PetrogenyMineralSet::const_iterator begin() const { return _petroset.begin(); } inline PetrogenyMineralSet::const_iterator end() const { return _petroset.end(); } }; class PetrogenyClassSetFacade { private: const PetrogenyClassSet & _petroset; public: PetrogenyClassSetFacade (const PetrogenyClassSet & petroset) : _petroset(petroset) {} inline PetrogenyClassSet::const_iterator begin() const { return _petroset.begin(); } inline PetrogenyClassSet::const_iterator end() const { return _petroset.end(); } }; mars::ptr< MineralDef > addMineral (const mars::ptr< MineralDef > & ptr); mars::ptr< MineralClass > addClass (const mars::ptr< MineralClass > & ptr); mars::ptr< MineralGroupDef > addGroup (const mars::ptr< MineralGroupDef > & ptr); void resolveReferences(); void createIndexes (); inline void init () { resolveReferences(); createIndexes(); } const mars::ptr< MineralDef > getMinByName (const std::string & sName) const; const mars::ptr< MineralClass > getClassByName (const std::string & sName) const; classes_const_iterator beginClasses (const MineralClass::Type enmcType) const; classes_const_iterator endClasses (const MineralClass::Type enmcType) const; inline ClassesSetFacade getClassesBySilica (const Silica ensSilica) const { return ClassesSetFacade (_classes.silica[ensSilica]); } PetrogenyMineralSetFacade getAssociatedMinerals (const std::string & sName) const; PetrogenyMineralSetFacade getAssociatedMinerals (const MineralPtr & pMin) const; PetrogenyMineralSetFacade getIncubatedMinerals (const std::string & sName) const; PetrogenyMineralSetFacade getIncubatedMinerals (const MineralPtr & pMin) const; PetrogenyMineralSetFacade getHostedMinerals (const std::string & sName) const; PetrogenyMineralSetFacade getHostedMinerals (const MineralPtr & pMin) const; PetrogenyClassSetFacade getMineralsByEnvironment (const std::string & sName) const; PetrogenyClassSetFacade getMineralsByEnvironment (const MinClassPtr & pClass) const; private: typedef std::map< std::string, mars::ptr< MineralDef > > MineralMap; typedef std::map< std::string, mars::ptr< MineralGroupDef > > MineralGroups; typedef std::map< MineralPtr, PetrogenyMineralSet > PetrogenyMineralMultiMap; typedef std::map< MinClassPtr, PetrogenyClassSet > PetrogenyClassMultiMap; typedef std::list< mars::ptr< MineralDef > > DirectMineralList; typedef std::map< std::string, DirectMineralList > MineralGroupMap; MineralMap _minerals; struct Groups { MineralGroups all; MineralGroupMap classes; } _groups; PetrogenyMineralMultiMap _associations, _protoliths, _hosts; struct Classes { ClassesMap all, igneous, sedimentary; ClassesSet silica[CountSilica]; } _classes; PetrogenyClassMultiMap _environments; PetrogenyMineralSet _endMineralPetrogeny; PetrogenyClassSet _endClassPetrogeny; void resolve( mars::WeakReference< MineralDef > & rWRef ); void resolve( mars::WeakReference< MineralClass > & rWRef ); void resolve( MineralReferenceList & list ); void resolve( MinClassReferenceList & list ); void resolveClassGroups (); static inline const std::string & getName (const MineralPtr & ptr) { if (ptr.getState() == MineralPtr::Weak) return ptr.getName(); else return ptr->name; } }; }