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

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

Jenga/common/String.hに対するテストを追加

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