source: dev/branches/egtra/ab5.0/jenga/include/common/Hashmap.h@ 808

Last change on this file since 808 was 808, checked in by イグトランス (egtra), 13 years ago

文字列のconst化など

File size: 5.4 KB
Line 
1#pragma once
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>
7
8namespace Jenga{
9namespace Common{
10
11template<class T>
12class ObjectInHashmap;
13template<class T>
14struct ObjectInHashmapHash;
15template<class T>
16struct ObjectInHashmapEqualTo;
17
18#define MAX_HASHMAP 65535
19template<class T> class Hashmap : boost::noncopyable
20{
21 typedef std::unordered_set<ObjectInHashmap<T>*, ObjectInHashmapHash<T>, ObjectInHashmapEqualTo<T>> MapType;
22 MapType map;
23
24 struct downcast
25 {
26 typedef T* result_type;
27 T* operator ()(ObjectInHashmap<T>* p) const
28 {
29 return boost::polymorphic_cast<T*>(p);
30 }
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 };
40
41public:
42
43 Hashmap()
44 {
45 }
46 ~Hashmap()
47 {
48 Clear();
49 }
50 void Clear()
51 {
52 boost::for_each(*this, boost::checked_deleter<T const>());
53 map.clear();
54 }
55
56 // 内容を破棄せずにすべて抜き取る
57 void PullOutAll()
58 {
59 map.clear();
60 }
61
62 bool Put(T* value)
63 {
64 if (value == nullptr)
65 {
66 throw std::invalid_argument("Hashmap::Put");
67 }
68 return map.insert(value).second;
69 }
70
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)
75 {
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()));
80 }
81
82 boost::iterator_range<const_local_iterator> GetHashArrayElement(std::string const& keyName) const
83 {
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()));
88 }
89
90 bool IsExistDuplicationKeyName(const std::string &keyName) const
91 {
92 ObjectInHashmapDummy<T> t(keyName);
93 return map.find(&t) != map.end();
94 }
95
96 bool IsExist( const T* value ) const
97 {
98 return map.find(const_cast<T*>(value)) != map.end();
99 }
100
101 const T *FindLike( const ObjectInHashmap<T>* value ) const
102 {
103 auto it = map.find(const_cast<ObjectInHashmap<T>*>(value));
104 return it != map.end()
105 ? boost::polymorphic_downcast<T const*>(*it)
106 : nullptr;
107 }
108
109
110 /////////////////////////////////////////////////////////////////
111 // イテレータ
112 /////////////////////////////////////////////////////////////////
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
127 {
128 return const_iterator(map.begin(), downcast());
129 }
130 const_iterator end() const
131 {
132 return const_iterator(map.end(), downcast());
133 }
134
135 // XMLシリアライズ用
136private:
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;
142 ar & BOOST_SERIALIZATION_NVP(objects);
143 Clear();
144 map = boost::copy_range<MapType>(objects);
145 }
146 template<class Archive> void save(Archive& ar, const unsigned int version) const
147 {
148 std::vector<T *> objects(begin(), end());
149 ar & BOOST_SERIALIZATION_NVP(objects);
150 }
151};
152
153template<class T>
154class ObjectInHashmap
155{
156public:
157
158 ObjectInHashmap()
159 {
160 }
161 ~ObjectInHashmap()
162 {
163 }
164
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 }
174};
175
176template<class T>
177struct ObjectInHashmapHash
178{
179 typedef std::size_t result_type;
180 std::size_t operator ()(ObjectInHashmap<T> const* x) const
181 {
182 return std::hash<std::string>()(x->GetKeyName());
183 }
184};
185
186// GetHashArrayElementなどで文字列から検索するために用いる。
187template<class T>
188class ObjectInHashmapDummy : public ObjectInHashmap<T>, boost::noncopyable
189{
190public:
191 explicit ObjectInHashmapDummy(std::string const& s) : str(s) {}
192
193 virtual std::string const& GetKeyName() const override
194 {
195 return str;
196 }
197
198 virtual bool IsDuplication(T const* value) const override
199 {
200 return value != nullptr
201 && value->ObjectInHashmap<T>::IsDuplication(str);
202 }
203
204private:
205 std::string const& str;
206};
207
208template<class T>
209struct ObjectInHashmapEqualTo
210{
211 typedef bool result_type;
212 bool operator ()(_In_ ObjectInHashmap<T> const* lhs, _In_ ObjectInHashmap<T> const* rhs) const
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};
226
227
228}}
Note: See TracBrowser for help on using the repository browser.