utils.hpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /*!
  2. \file utils.hpp
  3. \author Ha NGUYEN
  4. \since 06 Oct 2014
  5. \date 10 Feb 2015
  6. \brief Some utils for Xios
  7. */
  8. #ifndef __XIOS_UTILS_HPP__
  9. #define __XIOS_UTILS_HPP__
  10. #include <vector>
  11. #include <limits>
  12. #include "array_new.hpp"
  13. #include "exception.hpp"
  14. namespace xios
  15. {
  16. template<typename K>
  17. struct CArrayTraits {
  18. typedef K ArrayType;
  19. };
  20. template<typename K>
  21. struct CArrayBoolTraits : public CArrayTraits<K> {
  22. typedef bool Type;
  23. };
  24. template<>
  25. struct CArrayBoolTraits<CArray<bool,1> >
  26. {
  27. static inline void resizeArray(CArray<bool,1>& boolArray, const std::vector<int>& dimensionSize)
  28. {
  29. if (1 != dimensionSize.size())
  30. ERROR("utils::CArrayBoolTraits",
  31. <<"Dimension of resized array mismatch"<<endl
  32. <<"Dimension of resized is 1 "<<endl
  33. <<"Dimension of vetor resizing is "<< dimensionSize.size());
  34. boolArray.resize(dimensionSize[0]);
  35. }
  36. };
  37. template<>
  38. struct CArrayBoolTraits<CArray<bool,2> >
  39. {
  40. static inline void resizeArray(CArray<bool,2>& boolArray, const std::vector<int>& dimensionSize)
  41. {
  42. if (2 != dimensionSize.size())
  43. ERROR("utils::CArrayBoolTraits",
  44. <<"Dimension of resized array mismatch"<<endl
  45. <<"Dimension of resized is 2 "<<endl
  46. <<"Dimension of vetor resizing is "<< dimensionSize.size());
  47. boolArray.resize(dimensionSize[0], dimensionSize[1]);
  48. }
  49. };
  50. template<>
  51. struct CArrayBoolTraits<CArray<bool,3> >
  52. {
  53. static inline void resizeArray(CArray<bool,3>& boolArray, const std::vector<int>& dimensionSize)
  54. {
  55. if (3 != dimensionSize.size())
  56. ERROR("utils::CArrayBoolTraits",
  57. <<"Dimension of resized array mismatch"<<endl
  58. <<"Dimension of resized is 3 "<<endl
  59. <<"Dimension of vetor resizing is "<< dimensionSize.size());
  60. boolArray.resize(dimensionSize[0], dimensionSize[1], dimensionSize[2]);
  61. }
  62. };
  63. template<>
  64. struct CArrayBoolTraits<CArray<bool,4> >
  65. {
  66. static inline void resizeArray(CArray<bool,4>& boolArray, const std::vector<int>& dimensionSize)
  67. {
  68. if (4 != dimensionSize.size())
  69. ERROR("utils::CArrayBoolTraits",
  70. <<"Dimension of resized array mismatch"<<endl
  71. <<"Dimension of resized is 4 "<<endl
  72. <<"Dimension of vetor resizing is "<< dimensionSize.size());
  73. boolArray.resize(dimensionSize[0], dimensionSize[1], dimensionSize[2], dimensionSize[3]);
  74. }
  75. };
  76. template<>
  77. struct CArrayBoolTraits<CArray<bool,5> >
  78. {
  79. static inline void resizeArray(CArray<bool,5>& boolArray, const std::vector<int>& dimensionSize)
  80. {
  81. if (5 != dimensionSize.size())
  82. ERROR("utils::CArrayBoolTraits",
  83. <<"Dimension of resized array mismatch"<<endl
  84. <<"Dimension of resized is 5 "<<endl
  85. <<"Dimension of vetor resizing is "<< dimensionSize.size());
  86. boolArray.resize(dimensionSize[0], dimensionSize[1],
  87. dimensionSize[2], dimensionSize[3], dimensionSize[4]);
  88. }
  89. };
  90. template<>
  91. struct CArrayBoolTraits<CArray<bool,6> >
  92. {
  93. static inline void resizeArray(CArray<bool,6>& boolArray, const std::vector<int>& dimensionSize)
  94. {
  95. if (6 != dimensionSize.size())
  96. ERROR("utils::CArrayBoolTraits",
  97. <<"Dimension of resized array mismatch"<<endl
  98. <<"Dimension of resized is 6 "<<endl
  99. <<"Dimension of vetor resizing is "<< dimensionSize.size());
  100. boolArray.resize(dimensionSize[0], dimensionSize[1],
  101. dimensionSize[2], dimensionSize[3],
  102. dimensionSize[4], dimensionSize[5]);
  103. }
  104. };
  105. template<>
  106. struct CArrayBoolTraits<CArray<bool,7> >
  107. {
  108. static inline void resizeArray(CArray<bool,7>& boolArray, const std::vector<int>& dimensionSize)
  109. {
  110. if (7 != dimensionSize.size())
  111. ERROR("utils::CArrayBoolTraits",
  112. <<"Dimension of resized array mismatch"<<endl
  113. <<"Dimension of resized is 7 "<<endl
  114. <<"Dimension of vetor resizing is "<< dimensionSize.size());
  115. boolArray.resize(dimensionSize[0], dimensionSize[1],
  116. dimensionSize[2], dimensionSize[3],
  117. dimensionSize[4], dimensionSize[5], dimensionSize[6]);
  118. }
  119. };
  120. template <int v>
  121. struct Int2Type
  122. {
  123. enum { value = v };
  124. };
  125. template<typename T>
  126. union TypeToBytes {
  127. T value;
  128. unsigned char bytes[sizeof(T)];
  129. };
  130. template<typename T>
  131. struct HashAlgorithm
  132. {
  133. /*!
  134. Adapted version of one-at-a-time hash by Bob Jenkins,
  135. which is an expanded version of his Dr. Dobbs article.
  136. */
  137. static inline size_t jenkins_hash(const T& value)
  138. {
  139. TypeToBytes<T> u;
  140. (u.value) = value;
  141. size_t hash = 0;
  142. size_t length = sizeof(value);
  143. for (size_t i = 0; i < length; ++i)
  144. {
  145. hash += u.bytes[i];
  146. hash += (hash << 10);
  147. hash ^= (hash >> 6);
  148. }
  149. hash += (hash << 3);
  150. hash ^= (hash >> 11);
  151. hash += (hash << 15);
  152. return hash;
  153. }
  154. /*!
  155. Adatped version of (stupid) boost hash (but working)
  156. */
  157. static inline size_t boost_hash(const std::vector<T>& vec)
  158. {
  159. size_t hash = 0;
  160. int sizeVec = vec.size();
  161. for(int i = 0; i < sizeVec; ++i)
  162. {
  163. hash ^= i + 0x9e3779b9 + (hash << 6) + (hash >> 2);
  164. }
  165. return hash;
  166. }
  167. };
  168. template<typename T, typename Algo = Int2Type<0> >
  169. struct HashXIOS
  170. {
  171. std::size_t operator()(const T& val)
  172. {
  173. Algo al;
  174. return hash_value(val, al);
  175. }
  176. std::size_t hashVec(const std::vector<T>& vec)
  177. {
  178. return HashAlgorithm<T>::boost_hash(vec);
  179. }
  180. private:
  181. size_t hash_value(const T& val, Int2Type<0>)
  182. {
  183. return HashAlgorithm<T>::jenkins_hash(val);
  184. }
  185. };
  186. template<typename K>
  187. struct NumTraits {
  188. typedef K Type;
  189. };
  190. template<>
  191. struct NumTraits<unsigned long>
  192. {
  193. typedef unsigned long Scalar;
  194. typedef Scalar magnitudeType;
  195. static inline Scalar sfmin() {
  196. return std::numeric_limits<Scalar>::min();
  197. }
  198. static inline Scalar sfmax() {
  199. return std::numeric_limits<Scalar>::max();
  200. }
  201. static inline Scalar sflowest() {
  202. return -(std::numeric_limits<Scalar>::max());
  203. }
  204. static inline Scalar epsilon() {
  205. return std::numeric_limits<Scalar>::epsilon();
  206. }
  207. static inline Scalar dummy_precision() {
  208. return 0;
  209. }
  210. };
  211. template<>
  212. struct NumTraits<double>
  213. {
  214. typedef double Scalar;
  215. typedef Scalar magnitudeType;
  216. static inline Scalar sfmin() {
  217. return std::numeric_limits<Scalar>::min();
  218. }
  219. static inline Scalar sfmax() {
  220. return std::numeric_limits<Scalar>::max();
  221. }
  222. static inline Scalar sflowest() {
  223. return -(std::numeric_limits<Scalar>::max());
  224. }
  225. static inline Scalar epsilon() {
  226. return std::numeric_limits<Scalar>::epsilon();
  227. }
  228. static inline Scalar dummy_precision() {
  229. return 1e-12;
  230. }
  231. static inline bool isNan(const Scalar& v) {
  232. return (v != v);
  233. }
  234. };
  235. template<typename T>
  236. class CArrayStorage
  237. {
  238. public:
  239. typedef CArray<T,1> StorageType;
  240. public:
  241. CArrayStorage(const CArray<T,1>& arr) : values(arr) {}
  242. protected:
  243. const T& atIndex(int idx) const { return values(idx); }
  244. const StorageType& values;
  245. };
  246. template<typename T>
  247. class CVectorStorage
  248. {
  249. public:
  250. typedef std::vector<T> StorageType;
  251. public:
  252. CVectorStorage(const std::vector<T>& vec) : values(vec) {}
  253. protected:
  254. const T& atIndex(int idx) const { return values[idx]; }
  255. const StorageType& values;
  256. };
  257. template<
  258. typename T,
  259. template <class> class StoragePolicy = CVectorStorage
  260. >
  261. class XIOSComparatorWithIndex :
  262. public StoragePolicy<T>
  263. {
  264. public:
  265. typedef typename StoragePolicy<T>::StorageType StorageType;
  266. public:
  267. XIOSComparatorWithIndex(const StorageType& v) : StoragePolicy<T>(v) {}
  268. bool operator()(int a, int b) { return this->atIndex(a) < this->atIndex(b); }
  269. };
  270. template<
  271. typename T,
  272. template <class> class StoragePolicy = CVectorStorage
  273. >
  274. class XIOSLowerBoundWithIndex :
  275. public StoragePolicy<T>
  276. {
  277. public:
  278. typedef typename StoragePolicy<T>::StorageType StorageType;
  279. public:
  280. XIOSLowerBoundWithIndex(const StorageType &v) : StoragePolicy<T>(v) {}
  281. bool operator()(const int a, const T& b) { return this->atIndex(a) < b; }
  282. };
  283. template<
  284. typename T,
  285. template <class> class StoragePolicy = CVectorStorage
  286. >
  287. class XIOSBinarySearchWithIndex :
  288. public StoragePolicy<T>
  289. {
  290. public:
  291. typedef typename StoragePolicy<T>::StorageType StorageType;
  292. public:
  293. XIOSBinarySearchWithIndex(const StorageType& v) : StoragePolicy<T>(v) {}
  294. template<typename ForwardIterator>
  295. bool search(ForwardIterator first, ForwardIterator last, const T& val, ForwardIterator& position)
  296. {
  297. first = std::lower_bound(first, last, val, XIOSLowerBoundWithIndex<T, StoragePolicy>(this->values));
  298. position = first;
  299. return (first!=last && !(val<this->atIndex(*first)));
  300. }
  301. };
  302. struct XIOSAlgorithms
  303. {
  304. public:
  305. template<typename T, template <class> class StoragePolicy>
  306. static void sortWithIndex(const typename StoragePolicy<T>::StorageType& values, std::vector<int>& rv)
  307. {
  308. std::sort(rv.begin(), rv.end(), XIOSComparatorWithIndex<T, StoragePolicy>(values));
  309. }
  310. //! Fill in an vector with index begin at 0
  311. static void fillInIndex(int nbIndex, std::vector<int>& rvIndex)
  312. {
  313. if ((0 < nbIndex) && (nbIndex != rvIndex.size())) rvIndex.resize(nbIndex);
  314. for (int idx = 0; idx < nbIndex; ++idx) rvIndex[idx] = idx;
  315. }
  316. };
  317. }
  318. #endif // __UTILS_HPP__