source: XIOS/trunk/src/utils.hpp @ 676

Last change on this file since 676 was 671, checked in by rlacroix, 9 years ago

Avoid using C++11 feature for now.

File size: 8.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(value)];
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  template<typename T, typename Algo = Int2Type<0> >
176  struct HashXIOS
177  {
178    std::size_t operator()(const T& val)
179    {
180      Algo al;
181      return hash_value(val, al);
182    }
183
184  private:
185    size_t hash_value(const T& val, Int2Type<0>)
186    {
187      return HashAlgorithm<T>::jenkins_hash(val);
188    }
189  };
190
191template<typename K>
192struct NumTraits {
193    typedef K Type;
194};
195
196template<>
197struct NumTraits<unsigned long>
198{
199  typedef unsigned long Scalar;
200  typedef Scalar magnitudeType;
201
202  static inline Scalar sfmin() {
203    return std::numeric_limits<Scalar>::min();
204  }
205  static inline Scalar sfmax() {
206    return std::numeric_limits<Scalar>::max();
207  }
208};
209
210template<>
211struct NumTraits<double>
212{
213  typedef double Scalar;
214  typedef Scalar magnitudeType;
215
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};
223
224template<typename T>
225class CArrayStorage
226{
227public:
228  typedef CArray<T,1> StorageType;
229
230public:
231  CArrayStorage(const CArray<T,1>& arr) : values(arr) {}
232
233protected:
234  const T& atIndex(int idx) const { return values(idx); }
235  const StorageType& values;
236};
237
238template<typename T>
239class CVectorStorage
240{
241public:
242  typedef std::vector<T> StorageType;
243
244public:
245  CVectorStorage(const std::vector<T>& vec) : values(vec) {}
246
247protected:
248  const T& atIndex(int idx) const { return values[idx]; }
249  const StorageType& values;
250};
251
252
253template<
254  typename T,
255  template <class> class StoragePolicy = CVectorStorage
256  >
257class XIOSComparatorWithIndex :
258  public StoragePolicy<T>
259{
260public:
261  typedef typename  StoragePolicy<T>::StorageType StorageType;
262
263public:
264  XIOSComparatorWithIndex(const StorageType& v) : StoragePolicy<T>(v) {}
265  bool operator()(int a, int b) { return this->atIndex(a) < this->atIndex(b); }
266};
267
268template<
269  typename T,
270  template <class> class StoragePolicy = CVectorStorage
271  >
272class XIOSLowerBoundWithIndex :
273  public StoragePolicy<T>
274{
275public:
276  typedef typename  StoragePolicy<T>::StorageType StorageType;
277
278public:
279  XIOSLowerBoundWithIndex(const StorageType &v) : StoragePolicy<T>(v) {}
280  bool operator()(const int a, const T& b) { return this->atIndex(a) < b; }
281};
282
283template<
284  typename T,
285  template <class> class StoragePolicy = CVectorStorage
286  >
287class XIOSBinarySearchWithIndex :
288  public StoragePolicy<T>
289{
290public:
291  typedef typename  StoragePolicy<T>::StorageType StorageType;
292
293public:
294  XIOSBinarySearchWithIndex(const StorageType& v) : StoragePolicy<T>(v) {}
295
296  template<typename ForwardIterator>
297  bool search(ForwardIterator first, ForwardIterator last, const T& val, ForwardIterator& position)
298  {
299    first = std::lower_bound(first, last, val, XIOSLowerBoundWithIndex<T, StoragePolicy>(this->values));
300    position = first;
301    return (first!=last && !(val<this->atIndex(*first)));
302  }
303};
304
305
306struct XIOSAlgorithms
307{
308public:
309  template<typename T, template <class> class StoragePolicy>
310  static void sortWithIndex(const typename StoragePolicy<T>::StorageType& values, std::vector<int>& rv)
311  {
312    std::sort(rv.begin(), rv.end(), XIOSComparatorWithIndex<T, StoragePolicy>(values));
313  }
314
315  //! Fill in an vector with index begin at 0
316  static void fillInIndex(int nbIndex, std::vector<int>& rvIndex)
317  {
318    if ((0 < nbIndex) && (nbIndex != rvIndex.size())) rvIndex.resize(nbIndex);
319    for (int idx = 0; idx < nbIndex; ++idx) rvIndex[idx] = idx;
320  }
321};
322
323}
324
325#endif // __UTILS_HPP__
Note: See TracBrowser for help on using the repository browser.