[215] | 1 | #pragma once
|
---|
[803] | 2 | #include <unordered_set>
|
---|
| 3 | #include <boost/range/algorithm.hpp>
|
---|
| 4 | #include <boost/checked_delete.hpp>
|
---|
| 5 | #include <boost/iterator/transform_iterator.hpp>
|
---|
| 6 | #include <boost/cast.hpp>
|
---|
[215] | 7 |
|
---|
| 8 | namespace Jenga{
|
---|
| 9 | namespace Common{
|
---|
| 10 |
|
---|
[803] | 11 | template<class T>
|
---|
| 12 | class ObjectInHashmap;
|
---|
| 13 | template<class T>
|
---|
| 14 | struct ObjectInHashmapHash;
|
---|
| 15 | template<class T>
|
---|
| 16 | struct ObjectInHashmapEqualTo;
|
---|
[215] | 17 |
|
---|
| 18 | #define MAX_HASHMAP 65535
|
---|
[803] | 19 | template<class T> class Hashmap : boost::noncopyable
|
---|
[215] | 20 | {
|
---|
[803] | 21 | typedef std::unordered_set<ObjectInHashmap<T>*, ObjectInHashmapHash<T>, ObjectInHashmapEqualTo<T>> MapType;
|
---|
| 22 | MapType map;
|
---|
[215] | 23 |
|
---|
[803] | 24 | struct downcast
|
---|
[215] | 25 | {
|
---|
[803] | 26 | typedef T* result_type;
|
---|
| 27 | T* operator ()(ObjectInHashmap<T>* p) const
|
---|
| 28 | {
|
---|
| 29 | return boost::polymorphic_cast<T*>(p);
|
---|
[215] | 30 | }
|
---|
[803] | 31 | };
|
---|
| 32 | struct const_downcast
|
---|
| 33 | {
|
---|
| 34 | typedef T const* result_type;
|
---|
| 35 | T const* operator ()(ObjectInHashmap<T> const* p) const
|
---|
| 36 | {
|
---|
| 37 | return boost::polymorphic_cast<T const*>(p);
|
---|
| 38 | }
|
---|
| 39 | };
|
---|
[215] | 40 |
|
---|
[803] | 41 | public:
|
---|
| 42 |
|
---|
[215] | 43 | Hashmap()
|
---|
| 44 | {
|
---|
| 45 | }
|
---|
| 46 | ~Hashmap()
|
---|
| 47 | {
|
---|
| 48 | Clear();
|
---|
| 49 | }
|
---|
| 50 | void Clear()
|
---|
| 51 | {
|
---|
[803] | 52 | boost::for_each(*this, boost::checked_deleter<T const>());
|
---|
| 53 | map.clear();
|
---|
[215] | 54 | }
|
---|
| 55 |
|
---|
[270] | 56 | // 内容を破棄せずにすべて抜き取る
|
---|
| 57 | void PullOutAll()
|
---|
| 58 | {
|
---|
[803] | 59 | map.clear();
|
---|
[270] | 60 | }
|
---|
| 61 |
|
---|
[803] | 62 | bool Put(T* value)
|
---|
[215] | 63 | {
|
---|
[803] | 64 | if (value == nullptr)
|
---|
| 65 | {
|
---|
| 66 | throw std::invalid_argument("Hashmap::Put");
|
---|
[215] | 67 | }
|
---|
[803] | 68 | return map.insert(value).second;
|
---|
[215] | 69 | }
|
---|
| 70 |
|
---|
[803] | 71 | typedef boost::transform_iterator<downcast, typename MapType::local_iterator> local_iterator;
|
---|
| 72 | typedef boost::transform_iterator<const_downcast, typename MapType::const_local_iterator> const_local_iterator;
|
---|
| 73 |
|
---|
| 74 | boost::iterator_range<local_iterator> GetHashArrayElement(std::string const& keyName)
|
---|
[215] | 75 | {
|
---|
[803] | 76 | ObjectInHashmapDummy<T> t(keyName);
|
---|
| 77 | return boost::iterator_range<local_iterator>(
|
---|
| 78 | local_iterator(map.begin(map.bucket(&t)), downcast()),
|
---|
| 79 | local_iterator(map.end(map.bucket(&t)), downcast()));
|
---|
[215] | 80 | }
|
---|
[803] | 81 |
|
---|
| 82 | boost::iterator_range<const_local_iterator> GetHashArrayElement(std::string const& keyName) const
|
---|
[270] | 83 | {
|
---|
[803] | 84 | ObjectInHashmapDummy<T> t(keyName);
|
---|
| 85 | return boost::iterator_range<const_local_iterator>(
|
---|
| 86 | const_local_iterator(map.begin(map.bucket(&t)), const_downcast()),
|
---|
| 87 | const_local_iterator(map.end(map.bucket(&t)), const_downcast()));
|
---|
[270] | 88 | }
|
---|
[215] | 89 |
|
---|
[803] | 90 | bool IsExistDuplicationKeyName(const std::string &keyName) const
|
---|
[215] | 91 | {
|
---|
[803] | 92 | ObjectInHashmapDummy<T> t(keyName);
|
---|
| 93 | return map.find(&t) != map.end();
|
---|
[215] | 94 | }
|
---|
| 95 |
|
---|
[564] | 96 | bool IsExist( const T* value ) const
|
---|
| 97 | {
|
---|
[803] | 98 | return map.find(const_cast<T*>(value)) != map.end();
|
---|
[564] | 99 | }
|
---|
| 100 |
|
---|
[803] | 101 | const T *FindLike( const ObjectInHashmap<T>* value ) const
|
---|
[639] | 102 | {
|
---|
[803] | 103 | auto it = map.find(const_cast<ObjectInHashmap<T>*>(value));
|
---|
| 104 | return it != map.end()
|
---|
| 105 | ? boost::polymorphic_downcast<T const*>(*it)
|
---|
| 106 | : nullptr;
|
---|
[639] | 107 | }
|
---|
| 108 |
|
---|
| 109 |
|
---|
[215] | 110 | /////////////////////////////////////////////////////////////////
|
---|
| 111 | // イテレータ
|
---|
| 112 | /////////////////////////////////////////////////////////////////
|
---|
[803] | 113 | //typedef boost::transform_iterator<downcast, typename MapType::iterator> iterator;
|
---|
| 114 | typedef boost::transform_iterator<downcast, typename MapType::const_iterator> const_iterator;
|
---|
| 115 | typedef const_iterator iterator;
|
---|
| 116 | typedef typename MapType::size_type size_type;
|
---|
| 117 | typedef typename MapType::difference_type difference_type;
|
---|
| 118 | //iterator begin()
|
---|
| 119 | //{
|
---|
| 120 | // return iterator(map.begin(), downcast());
|
---|
| 121 | //}
|
---|
| 122 | //iterator end()
|
---|
| 123 | //{
|
---|
| 124 | // return iterator(map.end(), downcast());
|
---|
| 125 | //}
|
---|
| 126 | const_iterator begin() const
|
---|
[215] | 127 | {
|
---|
[803] | 128 | return const_iterator(map.begin(), downcast());
|
---|
[215] | 129 | }
|
---|
[803] | 130 | const_iterator end() const
|
---|
[215] | 131 | {
|
---|
[803] | 132 | return const_iterator(map.end(), downcast());
|
---|
[215] | 133 | }
|
---|
| 134 |
|
---|
| 135 | // XMLシリアライズ用
|
---|
| 136 | private:
|
---|
| 137 | friend class boost::serialization::access;
|
---|
| 138 | BOOST_SERIALIZATION_SPLIT_MEMBER();
|
---|
| 139 | template<class Archive> void load(Archive& ar, const unsigned int version)
|
---|
| 140 | {
|
---|
| 141 | std::vector<T *> objects;
|
---|
[803] | 142 | ar & BOOST_SERIALIZATION_NVP(objects);
|
---|
[215] | 143 | Clear();
|
---|
[803] | 144 | map = boost::copy_range<MapType>(objects);
|
---|
[215] | 145 | }
|
---|
| 146 | template<class Archive> void save(Archive& ar, const unsigned int version) const
|
---|
| 147 | {
|
---|
[803] | 148 | std::vector<T *> objects(begin(), end());
|
---|
| 149 | ar & BOOST_SERIALIZATION_NVP(objects);
|
---|
[215] | 150 | }
|
---|
| 151 | };
|
---|
| 152 |
|
---|
[803] | 153 | template<class T>
|
---|
| 154 | class ObjectInHashmap
|
---|
[215] | 155 | {
|
---|
[816] | 156 | protected:
|
---|
[215] | 157 | ObjectInHashmap()
|
---|
| 158 | {
|
---|
| 159 | }
|
---|
| 160 | ~ObjectInHashmap()
|
---|
| 161 | {
|
---|
| 162 | }
|
---|
| 163 |
|
---|
[816] | 164 | public:
|
---|
[215] | 165 | virtual const std::string &GetKeyName() const = 0;
|
---|
| 166 | virtual bool IsDuplication( const T *value ) const
|
---|
| 167 | {
|
---|
| 168 | return ( GetKeyName() == value->GetName() );
|
---|
| 169 | }
|
---|
| 170 | virtual bool IsDuplication( const std::string &keyName ) const
|
---|
| 171 | {
|
---|
| 172 | return ( GetKeyName() == keyName );
|
---|
| 173 | }
|
---|
[803] | 174 | };
|
---|
[215] | 175 |
|
---|
[803] | 176 | template<class T>
|
---|
| 177 | struct ObjectInHashmapHash
|
---|
| 178 | {
|
---|
| 179 | typedef std::size_t result_type;
|
---|
| 180 | std::size_t operator ()(ObjectInHashmap<T> const* x) const
|
---|
[215] | 181 | {
|
---|
[803] | 182 | return std::hash<std::string>()(x->GetKeyName());
|
---|
[215] | 183 | }
|
---|
[803] | 184 | };
|
---|
| 185 |
|
---|
| 186 | // GetHashArrayElementなどで文字列から検索するために用いる。
|
---|
| 187 | template<class T>
|
---|
| 188 | class ObjectInHashmapDummy : public ObjectInHashmap<T>, boost::noncopyable
|
---|
| 189 | {
|
---|
| 190 | public:
|
---|
| 191 | explicit ObjectInHashmapDummy(std::string const& s) : str(s) {}
|
---|
| 192 |
|
---|
| 193 | virtual std::string const& GetKeyName() const override
|
---|
[270] | 194 | {
|
---|
[803] | 195 | return str;
|
---|
[270] | 196 | }
|
---|
[803] | 197 |
|
---|
| 198 | virtual bool IsDuplication(T const* value) const override
|
---|
[215] | 199 | {
|
---|
[803] | 200 | return value != nullptr
|
---|
| 201 | && value->ObjectInHashmap<T>::IsDuplication(str);
|
---|
[215] | 202 | }
|
---|
[803] | 203 |
|
---|
| 204 | private:
|
---|
| 205 | std::string const& str;
|
---|
[215] | 206 | };
|
---|
| 207 |
|
---|
[803] | 208 | template<class T>
|
---|
| 209 | struct ObjectInHashmapEqualTo
|
---|
| 210 | {
|
---|
| 211 | typedef bool result_type;
|
---|
[808] | 212 | bool operator ()(_In_ ObjectInHashmap<T> const* lhs, _In_ ObjectInHashmap<T> const* rhs) const
|
---|
[803] | 213 | {
|
---|
| 214 | assert(lhs != nullptr);
|
---|
| 215 | assert(rhs != nullptr);
|
---|
| 216 | if (auto pl = dynamic_cast<T const*>(rhs))
|
---|
| 217 | {
|
---|
| 218 | return lhs->IsDuplication(pl);
|
---|
| 219 | }
|
---|
| 220 | else
|
---|
| 221 | {
|
---|
| 222 | return rhs->IsDuplication(dynamic_cast<T const*>(lhs));
|
---|
| 223 | }
|
---|
| 224 | }
|
---|
| 225 | };
|
---|
[215] | 226 |
|
---|
[803] | 227 |
|
---|
[215] | 228 | }}
|
---|