fbxmap.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /****************************************************************************************
  2. Copyright (C) 2015 Autodesk, Inc.
  3. All rights reserved.
  4. Use of this software is subject to the terms of the Autodesk license agreement
  5. provided at the time of installation or download, or which otherwise accompanies
  6. this software in either electronic or hard copy form.
  7. ****************************************************************************************/
  8. //! \file fbxmap.h
  9. #ifndef _FBXSDK_CORE_BASE_MAP_H_
  10. #define _FBXSDK_CORE_BASE_MAP_H_
  11. #include <fbxsdk/fbxsdk_def.h>
  12. #include <fbxsdk/core/base/fbxstring.h>
  13. #include <fbxsdk/core/base/fbxredblacktree.h>
  14. #include <fbxsdk/fbxsdk_nsbegin.h>
  15. class FbxObject;
  16. /** Default compare functor for FbxMap and FbxSet, which assumes operator < is defined.
  17. Here is examples of different compare class implementations:
  18. With Key = int
  19. \code
  20. class IntCompare
  21. {
  22. inline int operator()(int pKeyA, int pKeyB) const
  23. {
  24. return pKeyA < pKeyB ? -1 : (pKeyA > pKeyB ? 1 : 0);
  25. }
  26. };
  27. \endcode
  28. With Key = Class
  29. \code
  30. class ClassCompare
  31. {
  32. inline int operator()(const Class& pKeyA, const Class& pKeyB) const
  33. {
  34. return pKeyA < pKeyB ? -1 : (pKeyA > pKeyB ? 1 : 0);
  35. }
  36. };
  37. \endcode
  38. With Key = char*
  39. \code
  40. class StrCompare
  41. {
  42. inline int operator()(const char* pKeyA, const char* pKeyB) const
  43. {
  44. return strcmp(pKeyA, pKeyB);
  45. }
  46. };
  47. \endcode
  48. */
  49. template <typename Type> struct FbxLessCompare
  50. {
  51. inline int operator()(const Type& pLeft, const Type& pRight) const
  52. {
  53. return (pLeft < pRight) ? -1 : ((pRight < pLeft) ? 1 : 0);
  54. }
  55. };
  56. /** This class implements an efficient map based on key comparison, which stores key-value pairs.
  57. It executes insertion, deletion and query operations in O(log(n)) time. */
  58. template <typename Key, typename Type, typename Compare=FbxLessCompare<Key>, typename Allocator=FbxBaseAllocator> class FbxMap
  59. {
  60. protected:
  61. //! This class defines the key-value pairs used by the map.
  62. class KeyValuePair : private FbxPair<const Key, Type>
  63. {
  64. /*****************************************************************************************************************************
  65. ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
  66. *****************************************************************************************************************************/
  67. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  68. public:
  69. typedef const Key KeyType;
  70. typedef const Key ConstKeyType;
  71. typedef Type ValueType;
  72. typedef const Type ConstValueType;
  73. KeyValuePair(const Key& pFirst, const Type& pSecond) : FbxPair<const Key, Type>(pFirst, pSecond){}
  74. ConstKeyType& GetKey() const { return this->mFirst; }
  75. KeyType& GetKey(){ return this->mFirst; }
  76. ConstValueType& GetValue() const { return this->mSecond; }
  77. ValueType& GetValue(){ return this->mSecond; }
  78. #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
  79. };
  80. //! Declaration of the storage type used by the map.
  81. typedef FbxRedBlackTree<KeyValuePair, Compare, Allocator> StorageType;
  82. public:
  83. typedef Type ValueType;
  84. typedef Key KeyType;
  85. typedef typename StorageType::RecordType RecordType;
  86. typedef typename StorageType::IteratorType Iterator;
  87. typedef typename StorageType::ConstIteratorType ConstIterator;
  88. /** Preallocate memory.
  89. * \param pRecordCount The number of elements. */
  90. inline void Reserve(unsigned int pRecordCount)
  91. {
  92. mTree.Reserve(pRecordCount);
  93. }
  94. //! Retrieve the number of key-value pairs it holds.
  95. inline int GetSize() const
  96. {
  97. return mTree.GetSize();
  98. }
  99. /** Insert a key-value pair.
  100. * \param pKey The key.
  101. * \param pValue The value.
  102. * \return If the key is already present in the map, returns the existing pair and false; else returns the pointer to the new key-value and true. */
  103. inline FbxPair<RecordType*, bool> Insert(const KeyType& pKey, const ValueType& pValue)
  104. {
  105. return mTree.Insert(KeyValuePair(pKey, pValue));
  106. }
  107. /** Delete a key-value pair.
  108. * \param pKey The key.
  109. * \return \c true if success, \c false if key is not found. */
  110. inline bool Remove(const KeyType& pKey)
  111. {
  112. return mTree.Remove(pKey);
  113. }
  114. //! Clear the map.
  115. inline void Clear()
  116. {
  117. mTree.Clear();
  118. }
  119. //! Query whether the map is empty.
  120. inline bool Empty() const
  121. {
  122. return mTree.Empty();
  123. }
  124. //! Retrieve the begin iterator of the map.
  125. Iterator Begin()
  126. {
  127. return Iterator(Minimum());
  128. }
  129. //! Retrieve the end iterator of the map.
  130. Iterator End()
  131. {
  132. return Iterator();
  133. }
  134. //! Retrieve the begin iterator of the map.
  135. ConstIterator Begin() const
  136. {
  137. return ConstIterator(Minimum());
  138. }
  139. //! Retrieve the end iterator of the map.
  140. ConstIterator End() const
  141. {
  142. return ConstIterator();
  143. }
  144. /** Query a key.
  145. * \param pKey The key.
  146. * \return A key-value pair if success, NULL if the key is not found. */
  147. inline const RecordType* Find(const KeyType& pKey) const
  148. {
  149. return mTree.Find(pKey);
  150. }
  151. /** Query a key.
  152. * \param pKey The key.
  153. * \return A key-value pair if success, NULL if it's not found. */
  154. inline RecordType* Find(const KeyType& pKey)
  155. {
  156. return mTree.Find(pKey);
  157. }
  158. /** Find the key-value pair with the smallest key greater than a specified key.
  159. * \param pKey The key.
  160. * \return The found key-value pair. */
  161. inline const RecordType* UpperBound(const KeyType& pKey) const
  162. {
  163. return mTree.UpperBound(pKey);
  164. }
  165. /** Find the key-value pair with the smallest key greater than a specified key.
  166. * \param pKey The key.
  167. * \return The found key-value pair. */
  168. inline RecordType* UpperBound(const KeyType& pKey)
  169. {
  170. return mTree.UpperBound(pKey);
  171. }
  172. /** Retrieve the reference of the value in the key-value pairs in map.
  173. * \param pKey The key.
  174. * \return The reference of the value.
  175. * \remark If the key is not found, a new key-value pair will be inserted. */
  176. inline ValueType& operator[](const KeyType& pKey)
  177. {
  178. RecordType* lRecord = Find(pKey);
  179. if( !lRecord )
  180. {
  181. lRecord = Insert(pKey, ValueType()).mFirst;
  182. }
  183. return lRecord->GetValue();
  184. }
  185. //! Retrieve the key-value pair which is the minimum key in map.
  186. inline const RecordType* Minimum() const
  187. {
  188. return mTree.Minimum();
  189. }
  190. //! Retrieve the key-value pair which is the minimum key in map.
  191. inline RecordType* Minimum()
  192. {
  193. return mTree.Minimum();
  194. }
  195. //! Retrieve the key-value pair which is the maximum key in map.
  196. inline const RecordType* Maximum() const
  197. {
  198. return mTree.Maximum();
  199. }
  200. //! Retrieve the key-value pair which is the maximum key in map.
  201. inline RecordType* Maximum()
  202. {
  203. return mTree.Maximum();
  204. }
  205. /*****************************************************************************************************************************
  206. ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
  207. *****************************************************************************************************************************/
  208. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  209. inline FbxMap(){}
  210. inline FbxMap(const FbxMap& pMap) : mTree(pMap.mTree){}
  211. inline ~FbxMap(){ Clear(); }
  212. private:
  213. StorageType mTree;
  214. #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
  215. };
  216. /** A simple map class representing a dictionary-like data structure.
  217. * \nosubgrouping */
  218. template <class Key, class Type, class Compare> class FBXSDK_DLL FbxSimpleMap
  219. {
  220. public:
  221. typedef typename FbxMap<Key, Type, Compare>::RecordType* Iterator;
  222. /** Add a key-value pair as an element.
  223. * \param pKey The new key.
  224. * \param pValue The new value. */
  225. inline void Add(const Key& pKey, const Type& pValue)
  226. {
  227. mMap.Insert(pKey, pValue);
  228. }
  229. /** Find an element with a given key.
  230. * \param pKey The given key.
  231. * \return The iterator pointing to the found element or NULL if fails. */
  232. inline Iterator Find(const Key& pKey) const
  233. {
  234. return (Iterator)mMap.Find(pKey);
  235. }
  236. /** Find an element with a given value.
  237. * \param pValue The given value.
  238. * \return The iterator pointing to the found element or NULL if fails. */
  239. inline Iterator Find(const Type& pValue) const
  240. {
  241. Iterator lIterator = GetFirst();
  242. while( lIterator )
  243. {
  244. if( lIterator->GetValue() == pValue )
  245. {
  246. return lIterator;
  247. }
  248. lIterator = GetNext(lIterator);
  249. }
  250. return 0;
  251. }
  252. /** Remove an element from the map.
  253. * \param pIterator The given element. */
  254. inline void Remove(Iterator pIterator)
  255. {
  256. if( pIterator ) mMap.Remove(pIterator->GetKey());
  257. }
  258. /** Get the first element.
  259. * \return The the heading element. */
  260. inline Iterator GetFirst() const
  261. {
  262. return (Iterator)mMap.Minimum();
  263. }
  264. /** Get the next element of a given element.
  265. * \param pIterator The given element.
  266. * \return The next element. */
  267. inline Iterator GetNext(Iterator pIterator) const
  268. {
  269. return (Iterator)pIterator ? pIterator->Successor() : 0;
  270. }
  271. //! Remove all of the elements.
  272. inline void Clear()
  273. {
  274. mMap.Clear();
  275. }
  276. /** Reserve the space for given number elements.
  277. * \param pSize The given number. */
  278. inline void Reserve(int pSize)
  279. {
  280. mMap.Reserve(pSize);
  281. }
  282. /** Query the count of elements in the map.
  283. * \return The count of elements. */
  284. inline int GetCount() const
  285. {
  286. return mMap.GetSize();
  287. }
  288. /*****************************************************************************************************************************
  289. ** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
  290. *****************************************************************************************************************************/
  291. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  292. inline FbxSimpleMap(){}
  293. private:
  294. FbxMap<Key, Type, Compare> mMap;
  295. #endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
  296. };
  297. /** This class template declare a simple FbxObject map.
  298. * \nosubgrouping */
  299. template <class Type, class Compare> class FBXSDK_DLL FbxObjectMap : public FbxSimpleMap<Type, FbxObject*, Compare>
  300. {
  301. public:
  302. //! Constructor
  303. inline FbxObjectMap(){}
  304. /** Get the object contained in an element.
  305. * \param pIterator The given element.
  306. * \return The object.
  307. */
  308. inline FbxObject* Get(typename FbxSimpleMap<Type, FbxObject*, Compare>::Iterator pIterator)
  309. {
  310. return pIterator ? pIterator->GetValue() : 0;
  311. }
  312. };
  313. /** A class that maps strings to objects with a basic string comparator.
  314. * \nosubgrouping */
  315. class FBXSDK_DLL FbxObjectStringMap : public FbxObjectMap<FbxString, FbxStringCompare>
  316. {
  317. public:
  318. //! Constructor
  319. inline FbxObjectStringMap(){}
  320. };
  321. //! Call FbxFree on each element of the map, and then clear it.
  322. template <typename K, typename V, typename C, typename A> inline void FbxMapFree(FbxMap<K, V, C, A>& pMap)
  323. {
  324. for( typename FbxMap<K, V, C, A>::Iterator i = pMap.Begin(); i != pMap.End(); ++i )
  325. {
  326. FbxFree(i->GetValue());
  327. }
  328. pMap.Clear();
  329. }
  330. //! Call FbxDelete on each element of the map, and then clear it.
  331. template <typename K, typename V, typename C, typename A> inline void FbxMapDelete(FbxMap<K, V, C, A>& pMap)
  332. {
  333. for( typename FbxMap<K, V, C, A>::Iterator i = pMap.Begin(); i != pMap.End(); ++i )
  334. {
  335. FbxDelete(i->GetValue());
  336. }
  337. pMap.Clear();
  338. }
  339. //! Call Destroy on each element of the map, and then clear it.
  340. template <typename K, typename V, typename C, typename A> inline void FbxMapDestroy(FbxMap<K, V, C, A>& pMap)
  341. {
  342. for( typename FbxMap<K, V, C, A>::Iterator i = pMap.Begin(); i != pMap.End(); ++i )
  343. {
  344. i->GetValue()->Destroy();
  345. }
  346. pMap.Clear();
  347. }
  348. template class FbxSimpleMap<FbxString, FbxObject*, FbxStringCompare>;
  349. template class FbxObjectMap<FbxString, FbxStringCompare>;
  350. #include <fbxsdk/fbxsdk_nsend.h>
  351. #endif /* _FBXSDK_CORE_BASE_MAP_H_ */