#pragma once #include #include #include #include #include #include #include "moses/FF/FeatureFunction.h" namespace Moses { template struct DefaultFactory { typedef boost::shared_ptr ValuePtr; ValuePtr operator()() { return ValuePtr(new Value()); } }; template > class ThreadLocalByFeatureStorage { public: typedef boost::shared_ptr ValuePtr; typedef std::map NameValueMap; typedef boost::thread_specific_ptr TSNameValueMap; ThreadLocalByFeatureStorage(FeatureFunction* ff, Factory factory = Factory()) : m_ff(ff), m_factory(factory) {} virtual ~ThreadLocalByFeatureStorage() {} // provide empty virtual dtor virtual ValuePtr GetStored() { if(!m_nameMap.get()) m_nameMap.reset(new NameValueMap()); typename NameValueMap::iterator it = m_nameMap->find(m_ff->GetScoreProducerDescription()); if(it == m_nameMap->end()) { std::pair ret; ret = m_nameMap->insert( std::make_pair(m_ff->GetScoreProducerDescription(), m_factory())); return ret.first->second; } else { return it->second; } } virtual const ValuePtr GetStored() const { UTIL_THROW_IF2(!m_nameMap.get(), "No thread local storage has been created for: " << m_ff->GetScoreProducerDescription()); typename NameValueMap::const_iterator it = m_nameMap->find(m_ff->GetScoreProducerDescription()); UTIL_THROW_IF2(it == m_nameMap->end(), "No features stored for: " << m_ff->GetScoreProducerDescription()); return it->second; } private: FeatureFunction* m_ff; Factory m_factory; static TSNameValueMap m_nameMap; }; template typename ThreadLocalByFeatureStorage::TSNameValueMap ThreadLocalByFeatureStorage::m_nameMap; }