CTR-Pia  5.4.3
Game Communication Engine
 全て クラス ネームスペース 関数 変数 型定義 列挙型 列挙型の値 ページ
common_OffsetTreeMap.h
1 /*--------------------------------------------------------------------------------*
2  Copyright (C)Nintendo All rights reserved.
3 
4  These coded instructions, statements, and computer programs contain proprietary
5  information of Nintendo and/or its licensed developers and are protected by
6  national and international copyright laws. They may not be disclosed to third
7  parties or copied or duplicated in any form, in whole or in part, without the
8  prior written consent of Nintendo.
9 
10  The content herein is highly confidential and should be handled accordingly.
11  *--------------------------------------------------------------------------------*/
12 
13 
14 #pragma once
15 
16 #include <nn/pia/common/common_Definitions.h>
17 #include <nn/pia/common/common_TreeMap.h>
18 #include <nn/pia/common/common_PtrUtil.h>
19 
20 namespace nn
21 {
22 namespace pia
23 {
24 namespace common
25 {
26 
27 
28 /*!
29  @cond PRIVATE
30  @brief 要素のメンバにTreeMapNodeを持たせるタイプのツリーマップのクラスです。
31  */
32 template <typename Key_, typename Value_>
33 class OffsetTreeMap : public TreeMap<Key_>
34 {
35 public:
36  typedef Key_ Key;
37  typedef Value_ Value;
38  typedef TreeMapNode<Key> Node;
39 
40 
41  /*!
42  @brief デフォルトコンストラクタです。
43  */
44  OffsetTreeMap()
45  : TreeMap<Key>(), m_Offset(-1)
46  {
47  }
48 
49 
50  /*!
51  @brief Value の先頭アドレスから TreeMapNode へのオフセット値を設定します。
52  @details 使用する前に必ず呼び出す必要があります。
53  @param[in] offset 設定するオフセット。
54  */
55  void InitOffset(int32_t offset)
56  {
57  m_Offset = offset;
58  }
59 
60 
61  /*!
62  @brief すべての要素を削除します。
63  */
64  void Clear()
65  {
66  TreeMap<Key>::ClearNode();
67  }
68 
69 
70  /*!
71  @brief 指定したキーに対応する要素を検索します。
72  @param[in] key 検索するキー。
73  @return キーに対応する要素です。存在しない場合はNULLを返します。
74  */
75  Value* Find(const Key& key) const
76  {
77  return NodeToValueWithNullCheck(TreeMap<Key>::FindNode(key));
78  }
79 
80 
81  /*!
82  @brief 指定したキーに対応する要素を追加します。
83  @details 同じキーの要素が既に存在する場合は、要素を置き換えます。
84  @param[in] key 追加するキー。
85  @param[in] pValue 追加する要素。
86  @return 要素が置き換えられた場合は、置き換える前の古い要素を返します。その他の場合はNULLを返します。
87  */
88  Value* Insert(const Key& key, Value* pValue)
89  {
90  return NodeToValueWithNullCheck(TreeMap<Key>::InsertNode(key, ValueToNode(pValue)));
91  }
92 
93 
94  /*!
95  @brief 指定したキーの要素を削除します。
96  @details 指定したキーの要素が存在しなければ、削除は行われません。
97  @param[in] key 削除するキー。
98  @return 要素が削除された場合は、削除された要素を返します。削除されなかった場合はNULLを返します。
99  */
100  Value* Erase(const Key& key)
101  {
102  return NodeToValueWithNullCheck(TreeMap<Key>::EraseNode(key));
103  }
104 
105 
106  /*!
107  @brief 指定した要素を削除します。
108  @details このTreeMapの要素でない物を指定した場合の挙動は不定です。
109  @param[in] pValue 削除する要素。
110  */
111  void Erase(Value* pValue)
112  {
113  TreeMap<Key>::EraseNode(ValueToNode(pValue));
114  }
115 
116 
117  /*!
118  @brief 先頭の要素を取得します。
119  @return 先頭の要素です。空の場合はNULLを返します。
120  */
121  Value* Front() const
122  {
123  return NodeToValueWithNullCheck(TreeMap<Key>::FrontNode());
124  }
125 
126 
127  /*!
128  @brief 最後の要素を取得します。
129  @return 最後の要素です。
130  */
131  Value* Back() const
132  {
133  return NodeToValueWithNullCheck(TreeMap<Key>::BackNode());
134  }
135 
136 
137  /*!
138  @brief 指定した要素の1つ前の要素を取得します。
139  @details このTreeMapの要素でない物を指定した場合の挙動は不定です。
140  @param[in] pValue 基準とする要素。
141  @return 1つ前の要素です。先頭の要素を指定した場合はNULLを返します。
142  */
143  Value* Prev(const Value* pValue) const
144  {
145  return NodeToValueWithNullCheck(ValueToNode(pValue)->Prev());
146  }
147 
148 
149  /*!
150  @brief 指定した要素の1つ後の要素を取得します。
151  @details このTreeMapの要素でない物を指定した場合の挙動は不定です。
152  @param[in] pValue 基準とする要素。
153  @return 1つ後の要素です。最後の要素を指定した場合はNULLを返します。
154  */
155  Value* Next(const Value* pValue) const
156  {
157  return NodeToValueWithNullCheck(ValueToNode(pValue)->Next());
158  }
159 
160 
161  /*!
162  @brief 指定した要素がこのTreeMapに含まれているか調べます。
163  @param[in] pValue 調べる要素です。
164  @return このTreeMapの要素ならtrueを返します。
165  */
166  bool IsInclude(const Value* pValue) const
167  {
168  return TreeMap<Key>::IsIncludeNode(ValueToNode(pValue));
169  }
170 
171 
172  /*!
173  @brief イテレータです。
174  */
175  class Iterator
176  {
177  friend class OffsetTreeMap;
178 
179  private:
180  Iterator(const OffsetTreeMap* pTreeMap, Node* pNode)
181  : m_pTreeMap(pTreeMap), m_pNode(pNode)
182  {
183  m_pValue = m_pTreeMap->NodeToValueWithNullCheck(pNode);
184  }
185 
186  public:
187  Iterator& operator++()
188  {
189  m_pNode = m_pNode->Next();
190  m_pValue = m_pTreeMap->NodeToValueWithNullCheck(m_pNode);
191  return *this;
192  }
193 
194  bool operator==(const Iterator& x) const
195  {
196  return m_pValue == x.m_pValue;
197  }
198  bool operator!=(const Iterator& x) const
199  {
200  return m_pValue != x.m_pValue;
201  }
202 
203  Value& operator*()
204  {
205  return *m_pValue;
206  }
207  Value* operator->()
208  {
209  return m_pValue;
210  }
211 
212  private:
213  const OffsetTreeMap* m_pTreeMap;
214  Value* m_pValue;
215  Node* m_pNode;
216  };
217 
218 
219  /*!
220  @brief constイテレータです。
221  */
222  class ConstIterator
223  {
224  friend class OffsetTreeMap;
225 
226  private:
227  ConstIterator(const OffsetTreeMap* pTreeMap, const Node* pNode)
228  : m_pTreeMap(pTreeMap), m_pNode(pNode)
229  {
230  m_pValue = m_pTreeMap->NodeToValueWithNullCheck(pNode);
231  }
232 
233  public:
234  ConstIterator& operator++()
235  {
236  m_pNode = m_pNode->Next();
237  m_pValue = m_pTreeMap->NodeToValueWithNullCheck(m_pNode);
238  return *this;
239  }
240 
241  bool operator==(const ConstIterator& x) const
242  {
243  return m_pValue == x.m_pValue;
244  }
245  bool operator!=(const ConstIterator& x) const
246  {
247  return m_pValue != x.m_pValue;
248  }
249 
250  const Value& operator*()
251  {
252  return *m_pValue;
253  }
254  const Value* operator->()
255  {
256  return m_pValue;
257  }
258 
259  private:
260  const OffsetTreeMap* m_pTreeMap;
261  const Value* m_pValue;
262  const Node* m_pNode;
263  };
264 
265 
266  /*!
267  @brief robustイテレータです。
268  @details イテレータが指し示す要素を削除してもイテレータを継続できます。
269  要素の追加やイテレータが指し示していない要素の削除をした場合はイテレータを継続できません。
270  */
271  class RobustIterator
272  {
273  friend class OffsetTreeMap;
274 
275  private:
276  RobustIterator(const OffsetTreeMap* pTreeMap, Node* pNode)
277  : m_pTreeMap(pTreeMap)
278  {
279  m_pValue = m_pTreeMap->NodeToValueWithNullCheck(pNode);
280  m_pNextNode = (pNode != NULL) ? pNode->Next() : NULL;
281  }
282 
283  public:
284  RobustIterator& operator++()
285  {
286  if (m_pNextNode != NULL)
287  {
288  m_pValue = m_pTreeMap->NodeToValue(m_pNextNode);
289  m_pNextNode = m_pNextNode->Next();
290  }
291  else
292  {
293  m_pValue = NULL;
294  }
295  return *this;
296  }
297 
298  bool operator==(const RobustIterator& x) const
299  {
300  return m_pValue == x.m_pValue;
301  }
302  bool operator!=(const RobustIterator& x) const
303  {
304  return m_pValue != x.m_pValue;
305  }
306 
307  Value& operator*()
308  {
309  return *m_pValue;
310  }
311  Value* operator->()
312  {
313  return m_pValue;
314  }
315 
316  private:
317  const OffsetTreeMap* m_pTreeMap;
318  Value* m_pValue;
319  Node* m_pNextNode;
320  };
321 
322 
323  /*!
324  @brief 先頭の要素を指すIteratorを取得します。
325 
326  @return 先頭の要素を指すIterator。
327  */
328  Iterator Begin() const
329  {
330  return Iterator(this, TreeMap<Key>::FrontNode());
331  }
332 
333 
334  /*!
335  @brief 末尾の要素の次を指すIteratorを取得します。
336 
337  @return 末尾の要素の次を指すIterator。
338  */
339  Iterator End() const
340  {
341  return Iterator(this, NULL);
342  }
343 
344 
345  /*!
346  @brief 指定したキーの値以上で最小のキーを持つ要素を指すIteratorを取得します。
347 
348  @return 指定したキーの値以上で最小のキーを持つ要素を指すIterator。
349  */
350  Iterator LowerBound(const Key& key) const
351  {
352  return Iterator(this, TreeMap<Key>::LowerBoundNode(key));
353  }
354 
355 
356  /*!
357  @brief 先頭の要素を指すConstIteratorを取得します。
358 
359  @return 先頭の要素を指すConstIterator。
360  */
361  ConstIterator ConstBegin() const
362  {
363  return ConstIterator(this, TreeMap<Key>::FrontNode());
364  }
365 
366 
367  /*!
368  @brief 末尾の要素の次を指すConstIteratorを取得します。
369 
370  @return 末尾の要素の次を指すConstIterator。
371  */
372  ConstIterator ConstEnd() const
373  {
374  return ConstIterator(this, NULL);
375  }
376 
377 
378  /*!
379  @brief 指定したキーの値以上で最小のキーを持つ要素を指すConstIteratorを取得します。
380 
381  @return 指定したキーの値以上で最小のキーを持つ要素を指すConstIterator。
382  */
383  ConstIterator ConstLowerBound(const Key& key) const
384  {
385  return ConstIterator(this, TreeMap<Key>::LowerBoundNode(key));
386  }
387 
388 
389  /*!
390  @brief 先頭の要素を指すRobustIteratorを取得します。
391 
392  @return 先頭の要素を指すRobustIterator。
393  */
394  RobustIterator RobustBegin() const
395  {
396  return RobustIterator(this, TreeMap<Key>::FrontNode());
397  }
398 
399 
400  /*!
401  @brief 末尾の要素の次を指すRobustIteratorを取得します。
402 
403  @return 末尾の要素の次を指すRobustIterator。
404  */
405  RobustIterator RobustEnd() const
406  {
407  return RobustIterator(this, NULL);
408  }
409 
410 
411  /*!
412  @brief 指定したキーの値以上で最小のキーを持つ要素を指すRobustIteratorを取得します。
413 
414  @return 指定したキーの値以上で最小のキーを持つ要素を指すRobustIterator。
415  */
416  RobustIterator RobustLowerBound(const Key& key) const
417  {
418  return RobustIterator(this, TreeMap<Key>::LowerBoundNode(key));
419  }
420 
421 private:
422  int32_t m_Offset;
423 
424  Node* ValueToNode(const Value* pObj) const
425  {
426  return reinterpret_cast<Node*>(PtrUtil::addOffset(pObj, m_Offset));
427  }
428 
429  Value* NodeToValue(const Node* pNode) const
430  {
431  return reinterpret_cast<Value*>(PtrUtil::addOffset(pNode, -m_Offset));
432  }
433 
434  Value* NodeToValueWithNullCheck(const Node* pNode) const
435  {
436  if (pNode)
437  return reinterpret_cast<Value*>(PtrUtil::addOffset(pNode, -m_Offset));
438  else
439  return NULL;
440  }
441 
442  OffsetTreeMap(const OffsetTreeMap&);
443  OffsetTreeMap& operator=(const OffsetTreeMap&);
444 };
445 //! @endcond
446 }
447 }
448 } // end of namespace nn::pia::common