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
RevLine 
[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
8namespace Jenga{
9namespace Common{
10
[803]11template<class T>
12class ObjectInHashmap;
13template<class T>
14struct ObjectInHashmapHash;
15template<class T>
16struct ObjectInHashmapEqualTo;
[215]17
18#define MAX_HASHMAP 65535
[803]19template<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]41public:
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シリアライズ用
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;
[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]153template<class T>
154class ObjectInHashmap
[215]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 }
[803]174};
[215]175
[803]176template<class T>
177struct 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などで文字列から検索するために用いる。
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
[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
204private:
205 std::string const& str;
[215]206};
207
[803]208template<class T>
209struct 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}}
Note: See TracBrowser for help on using the repository browser.