#include #include #include #include #include #include #include #include #pragma once namespace Jenga{ namespace Common{ template class ObjectInHashmap; template struct ObjectInHashmapHash; template struct ObjectInHashmapEqualTo; #define MAX_HASHMAP 65535 template class Hashmap : boost::noncopyable { typedef std::unordered_set*, ObjectInHashmapHash, ObjectInHashmapEqualTo> MapType; MapType map; struct downcast { typedef T* result_type; T* operator ()(ObjectInHashmap* p) const { return boost::polymorphic_cast(p); } }; struct const_downcast { typedef T const* result_type; T const* operator ()(ObjectInHashmap const* p) const { return boost::polymorphic_cast(p); } }; public: Hashmap() { } ~Hashmap() { Clear(); } void Clear() { boost::for_each(*this, boost::checked_deleter()); map.clear(); } // 内容を破棄せずにすべて抜き取る void PullOutAll() { map.clear(); } bool Put(T* value) { if (value == nullptr) { throw std::invalid_argument("Hashmap::Put"); } return map.insert(value).second; } typedef boost::transform_iterator local_iterator; typedef boost::transform_iterator const_local_iterator; boost::iterator_range GetHashArrayElement(std::string const& keyName) { ObjectInHashmapDummy t(keyName); return boost::iterator_range( local_iterator(map.begin(map.bucket(&t)), downcast()), local_iterator(map.end(map.bucket(&t)), downcast())); } boost::iterator_range GetHashArrayElement(std::string const& keyName) const { ObjectInHashmapDummy t(keyName); return boost::iterator_range( const_local_iterator(map.begin(map.bucket(&t)), const_downcast()), const_local_iterator(map.end(map.bucket(&t)), const_downcast())); } bool IsExistDuplicationKeyName(const std::string &keyName) const { ObjectInHashmapDummy t(keyName); return map.find(&t) != map.end(); } bool IsExist( const T* value ) const { return map.find(const_cast(value)) != map.end(); } const T *FindLike( const ObjectInHashmap* value ) const { auto it = map.find(const_cast*>(value)); return it != map.end() ? boost::polymorphic_downcast(*it) : nullptr; } ///////////////////////////////////////////////////////////////// // イテレータ ///////////////////////////////////////////////////////////////// //typedef boost::transform_iterator iterator; typedef boost::transform_iterator const_iterator; typedef const_iterator iterator; typedef typename MapType::size_type size_type; typedef typename MapType::difference_type difference_type; //iterator begin() //{ // return iterator(map.begin(), downcast()); //} //iterator end() //{ // return iterator(map.end(), downcast()); //} const_iterator begin() const { return const_iterator(map.begin(), downcast()); } const_iterator end() const { return const_iterator(map.end(), downcast()); } // XMLシリアライズ用 private: friend class boost::serialization::access; BOOST_SERIALIZATION_SPLIT_MEMBER(); template void load(Archive& ar, const unsigned int version) { std::vector objects; ar & BOOST_SERIALIZATION_NVP(objects); Clear(); map = boost::copy_range(objects); } template void save(Archive& ar, const unsigned int version) const { std::vector objects(begin(), end()); ar & BOOST_SERIALIZATION_NVP(objects); } }; template class ObjectInHashmap { protected: ObjectInHashmap() { } ~ObjectInHashmap() { } public: virtual const std::string &GetKeyName() const = 0; virtual bool IsDuplication( const T *value ) const { return ( GetKeyName() == value->GetName() ); } virtual bool IsDuplication( const std::string &keyName ) const { return ( GetKeyName() == keyName ); } }; template struct ObjectInHashmapHash { typedef std::size_t result_type; std::size_t operator ()(ObjectInHashmap const* x) const { return std::hash()(x->GetKeyName()); } }; // GetHashArrayElementなどで文字列から検索するために用いる。 template class ObjectInHashmapDummy : public ObjectInHashmap, boost::noncopyable { public: explicit ObjectInHashmapDummy(std::string const& s) : str(s) {} virtual std::string const& GetKeyName() const override { return str; } virtual bool IsDuplication(T const* value) const override { return value != nullptr && value->ObjectInHashmap::IsDuplication(str); } private: std::string const& str; }; template struct ObjectInHashmapEqualTo { typedef bool result_type; bool operator ()(_In_ ObjectInHashmap const* lhs, _In_ ObjectInHashmap const* rhs) const { assert(lhs != nullptr); assert(rhs != nullptr); if (auto pl = dynamic_cast(rhs)) { return lhs->IsDuplication(pl); } else { return rhs->IsDuplication(dynamic_cast(lhs)); } } }; }}