source: XIOS2/trunk/src/utils.hpp @ 2399

Last change on this file since 2399 was 1474, checked in by oabramkina, 7 years ago

DEV_CMIP6: porting changes in r1471.

Now DEV_CMIP6 compiles with PGI.

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