cartobase  5.0.5
converter.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef CARTOBASE_TYPE_CONVERTER_H
35 #define CARTOBASE_TYPE_CONVERTER_H
36 
38 #include <cartobase/type/types.h>
39 #include <cartobase/type/limits.h>
41 
42 namespace carto
43 {
58  {
59  public:
61  RescalerInfo();
62 
64  bool explicitRescale() const;
65 
70 
71  double vmin;
72  double vmax;
73  double omin;
74  double omax;
75  };
76 
78  template<typename INP, typename OUTP>
80  {
81  public:
82  void convert( const INP &in, OUTP & out ) const;
83  };
84 
85  // Conversion with Void
86  template <typename OUTP>
87  class RawConverter<Void, OUTP>
88  {
89  public:
90  void convert( const Void &, OUTP & out ) const
91  {
92  out = OUTP( 1 );
93  }
94  };
95 
96 
97  template <typename INP>
98  class RawConverter<INP, Void>
99  {
100  public:
101  void convert( const INP &, Void & ) const
102  {
103  }
104  };
105 
106 
107  template<>
109  {
110  public:
111  void convert( const Void &, Void & ) const
112  {
113  }
114  };
115 
116  template<typename INP, typename OUTP>
118  {
119  public:
121  DefaultedRescalerInfo( const RescalerInfo & info );
122 
123  double getScale() const
124  {
125  return _scale;
126  }
127  OUTP getScaledValue( INP value ) const;
128 
129  private:
130  double getscale() const;
131 
132  INP _defaultedvmin;
133  INP _defaultedvmax;
134  OUTP _defaultedomin;
135  OUTP _defaultedomax;
136 
137  double _scale;
138  };
139 
141  template<typename INP, typename OUTP>
142  class Rescaler
143  {
144  public:
145  Rescaler();
146  Rescaler( const RescalerInfo & info );
147  void convert( const INP &in, OUTP & out ) const;
148 
149  private:
150  DefaultedRescalerInfo<INP, OUTP> _defaulted_info;
151  };
152 
153 
157  template<typename INP, typename OUTP, bool MODE>
159 
163  template<typename INP, typename OUTP>
165  {
166  public:
167  static OUTP* alloc( const INP &in );
168  };
169 
170 
172  template<typename INP, typename OUTP>
173  class ConverterSwitch<INP,OUTP,true> : public Rescaler<INP,OUTP>
174  {
175  public:
177  : Rescaler<INP,OUTP>( info ) {}
178  ConverterSwitch() : Rescaler<INP,OUTP>() {}
179  };
180 
181 
191  template<typename INP, typename OUTP>
192  class ConverterSwitch<INP,OUTP,false> : public RawConverter<INP,OUTP>
193  {
194  public:
196  : RawConverter<INP,OUTP>() {}
197  ConverterSwitch() : RawConverter<INP,OUTP>() {}
198  };
199 
200 
204  template<typename INP, typename OUTP>
206  : public ConverterSwitch<INP,OUTP,
207  std::numeric_limits<INP>::is_specialized
208  && std::numeric_limits<OUTP>::is_bounded >
209  {
210  public:
211  SmartConverter( const RescalerInfo & info )
212  : ConverterSwitch<INP,OUTP,
213  std::numeric_limits<INP>::is_specialized
214  && std::numeric_limits<OUTP>::is_bounded >( info ) {}
215  };
216 
217 
219  template <class INP,class OUTP>
220  class Converter
221  {
222  public :
223  Converter( bool rescale = false ) : _rescale( rescale ), _info() {}
224  Converter( bool rescale, const RescalerInfo & info )
225  : _rescale( rescale ), _info(info) {}
226  virtual ~Converter() {}
227 
237  OUTP* operator () ( const INP &in ) const;
243  virtual void convert( const INP &in, OUTP & out ) const;
244 
245  protected:
246  bool _rescale;
248  };
249 
250 
256  template <typename INP, typename OUTP>
257  class ShallowConverter : public Converter<INP, OUTP>
258  {
259  public:
260  ShallowConverter( bool rescale = false )
261  : Converter<INP, OUTP>( rescale ) {}
262  ShallowConverter( bool rescale, RescalerInfo & info )
263  : Converter<INP, OUTP>( rescale, info ) {}
264  };
265 
266  // implementation
267  template<typename INP, typename OUTP>
268  inline
269  Rescaler<INP,OUTP>::Rescaler() : _defaulted_info()
270  {
271  }
272 
273  template<typename INP, typename OUTP>
274  inline
276  _defaulted_info(info)
277  {
278  }
279 
280  template<typename INP, typename OUTP>
281  inline
282  void Rescaler<INP,OUTP>::convert( const INP &in, OUTP & out ) const
283  {
284  // TODO: this extremely sub-optimal...
285  // (but hopefullty extremely rarely used)
286  out = _defaulted_info.getScaledValue(in);
287  }
288 
289 
290 #define CARTO_SPECIALIZED_RAWCONVERTER_ROUNDED_CONVERT( INP , OUTP ) \
291 template<> \
292 inline \
293 void RawConverter< INP , OUTP >::convert( const INP &in, OUTP & out ) const \
294 { \
295  out = static_cast<OUTP>( rint( in ) ); \
296 }
297  // Specialization for integer conversions rawconverter methods
298  // In the case of conversion to integer types, we must round values,
299  // not only convert.
312 #undef CARTO_SPECIALIZED_RAWCONVERTER_ROUNDED_CONVERT
313 
314 
315  template<typename INP, typename OUTP>
316  inline
317  void RawConverter<INP,OUTP>::convert( const INP &in, OUTP & out ) const
318  {
319  out = static_cast<OUTP>( in );
320  }
321 
322  template<class INP, class OUTP>
323  inline OUTP* ConverterAllocator<INP,OUTP>::alloc( const INP & )
324  {
325  return new OUTP;
326  }
327 
328  // Converter
329  template<class INP, class OUTP>
330  inline OUTP* Converter<INP,OUTP>::operator () ( const INP & in ) const
331  {
332  OUTP *out = ConverterAllocator<INP,OUTP>::alloc( in );
333  convert( in, *out );
334  return out;
335  }
336 
337  template<class INP, class OUTP>
338  inline void
339  Converter<INP,OUTP>::convert( const INP &in, OUTP & out ) const
340  {
341  if( _rescale )
342  {
343  SmartConverter<INP,OUTP> sc(this->_info);
344  sc.convert( in, out );
345  }
346  else
347  {
349  rc.convert( in, out );
350  }
351  }
352 
353 #if __cplusplus >= 201103L
354  template<typename T>
355  inline T min_limit()
356  {
357  // in C++11 we have std::numeric_limits<T>::lowest()
359  }
360 
361 #else
362  namespace internal
363  {
364  // use a class to get partial specialization
365  template <typename T, bool is_min=std::numeric_limits<T>::is_integer>
367  {
368  public:
369  static T lowest()
370  {
372  }
373  };
374 
375  template <typename T>
376  class limits_complement<T, false>
377  {
378  public:
379  static T lowest()
380  {
383  return 0 - std::numeric_limits<T>::max();
384  }
385  };
386  }
387 
388  template<typename T>
389  inline T min_limit()
390  {
392  }
393 #endif
394 
395  template<typename T>
396  inline bool ismin_limit( T value ){
397  return ( value == carto::min_limit<T>() );
398  }
399 
400  template<typename T>
401  inline bool ismax_limit( T value ){
402  return ( value == std::numeric_limits<T>::max() );
403  }
404 
405  template<typename TYPE, typename TEST>
406  inline bool isvalidvalue( TYPE value ){
408  return ( static_cast<TYPE>(carto::min_limit<TEST>()) <= value )
409  && ( value <= static_cast<TYPE>(std::numeric_limits<TEST>::max()) );
410  }
411 
412  template<typename TYPE>
413  inline TYPE getcheckedmin( double min ) {
414  return ( carto::isvalidvalue<double, TYPE>( min ) ?
415  static_cast<TYPE>( min ) :
416  carto::min_limit<TYPE>() );
417  }
418 
419  template<typename TYPE>
420  inline TYPE getcheckedmax( double max ) {
421  return ( carto::isvalidvalue<double, TYPE>( max ) ?
422  static_cast<TYPE>( max ) :
424  }
425 
426  /*
427  * DefaultedRescalerInfo methods implementation
428  */
429 
430  template<typename INP, typename OUTP>
431  inline OUTP DefaultedRescalerInfo<INP,OUTP>::getScaledValue( INP value ) const
432  {
433  OUTP result;
434  RawConverter<double, OUTP> doubleconverter;
435  double scaledvalue;
436 
437  scaledvalue = ( value - this->_defaultedvmin ) * _scale
438  + this->_defaultedomin;
439 
440  if ( scaledvalue < static_cast<double>(carto::min_limit<OUTP>())) {
441  result = carto::min_limit<OUTP>();
442  } else if ( scaledvalue > static_cast<double>(std::numeric_limits<OUTP>::max()) ) {
444  } else {
445  doubleconverter.convert( scaledvalue, result );
446  }
447 
448 // if (value != 0)
449 // std::cout << "Scale value " << carto::toString(value)
450 // << "(" << carto::DataTypeCode<INP>::name() << ")"
451 // << " to " << carto::toString(result)
452 // << "(" << carto::DataTypeCode<OUTP>::name() << ")"
453 // << "scale is " << carto::toString(_scale) << ")"
454 // << std::endl;
455  return result;
456  }
457 
458  extern template class DefaultedRescalerInfo<int8_t, int8_t>;
459  extern template class DefaultedRescalerInfo<int8_t, uint8_t>;
460  extern template class DefaultedRescalerInfo<int8_t, int16_t>;
461  extern template class DefaultedRescalerInfo<int8_t, uint16_t>;
462  extern template class DefaultedRescalerInfo<int8_t, int32_t>;
463  extern template class DefaultedRescalerInfo<int8_t, uint32_t>;
464  extern template class DefaultedRescalerInfo<int8_t, float>;
465  extern template class DefaultedRescalerInfo<int8_t, double>;
466 
467  extern template class DefaultedRescalerInfo<uint8_t, int8_t>;
468  extern template class DefaultedRescalerInfo<uint8_t, uint8_t>;
469  extern template class DefaultedRescalerInfo<uint8_t, int16_t>;
470  extern template class DefaultedRescalerInfo<uint8_t, uint16_t>;
471  extern template class DefaultedRescalerInfo<uint8_t, int32_t>;
472  extern template class DefaultedRescalerInfo<uint8_t, uint32_t>;
473  extern template class DefaultedRescalerInfo<uint8_t, float>;
474  extern template class DefaultedRescalerInfo<uint8_t, double>;
475 
476  extern template class DefaultedRescalerInfo<int16_t, int8_t>;
477  extern template class DefaultedRescalerInfo<int16_t, uint8_t>;
478  extern template class DefaultedRescalerInfo<int16_t, int16_t>;
479  extern template class DefaultedRescalerInfo<int16_t, uint16_t>;
480  extern template class DefaultedRescalerInfo<int16_t, int32_t>;
481  extern template class DefaultedRescalerInfo<int16_t, uint32_t>;
482  extern template class DefaultedRescalerInfo<int16_t, float>;
483  extern template class DefaultedRescalerInfo<int16_t, double>;
484 
485  extern template class DefaultedRescalerInfo<uint16_t, int8_t>;
486  extern template class DefaultedRescalerInfo<uint16_t, uint8_t>;
487  extern template class DefaultedRescalerInfo<uint16_t, int16_t>;
488  extern template class DefaultedRescalerInfo<uint16_t, uint16_t>;
489  extern template class DefaultedRescalerInfo<uint16_t, int32_t>;
490  extern template class DefaultedRescalerInfo<uint16_t, uint32_t>;
491  extern template class DefaultedRescalerInfo<uint16_t, float>;
492  extern template class DefaultedRescalerInfo<uint16_t, double>;
493 
494  extern template class DefaultedRescalerInfo<int32_t, int8_t>;
495  extern template class DefaultedRescalerInfo<int32_t, uint8_t>;
496  extern template class DefaultedRescalerInfo<int32_t, int16_t>;
497  extern template class DefaultedRescalerInfo<int32_t, uint16_t>;
498  extern template class DefaultedRescalerInfo<int32_t, int32_t>;
499  extern template class DefaultedRescalerInfo<int32_t, uint32_t>;
500  extern template class DefaultedRescalerInfo<int32_t, float>;
501  extern template class DefaultedRescalerInfo<int32_t, double>;
502 
503  extern template class DefaultedRescalerInfo<uint32_t, int8_t>;
504  extern template class DefaultedRescalerInfo<uint32_t, uint8_t>;
505  extern template class DefaultedRescalerInfo<uint32_t, int16_t>;
506  extern template class DefaultedRescalerInfo<uint32_t, uint16_t>;
507  extern template class DefaultedRescalerInfo<uint32_t, int32_t>;
508  extern template class DefaultedRescalerInfo<uint32_t, uint32_t>;
509  extern template class DefaultedRescalerInfo<uint32_t, float>;
510  extern template class DefaultedRescalerInfo<uint32_t, double>;
511 
512  extern template class DefaultedRescalerInfo<float, int8_t>;
513  extern template class DefaultedRescalerInfo<float, uint8_t>;
514  extern template class DefaultedRescalerInfo<float, int16_t>;
515  extern template class DefaultedRescalerInfo<float, uint16_t>;
516  extern template class DefaultedRescalerInfo<float, int32_t>;
517  extern template class DefaultedRescalerInfo<float, uint32_t>;
518  extern template class DefaultedRescalerInfo<float, float>;
519  extern template class DefaultedRescalerInfo<float, double>;
520 
521  extern template class DefaultedRescalerInfo<double, int8_t>;
522  extern template class DefaultedRescalerInfo<double, uint8_t>;
523  extern template class DefaultedRescalerInfo<double, int16_t>;
524  extern template class DefaultedRescalerInfo<double, uint16_t>;
525  extern template class DefaultedRescalerInfo<double, int32_t>;
526  extern template class DefaultedRescalerInfo<double, uint32_t>;
527  extern template class DefaultedRescalerInfo<double, float>;
528  extern template class DefaultedRescalerInfo<double, double>;
529 
530  // These three specializations seem to be needed in order to compile
531  // the AimsFileConvert command.
532  extern template class DefaultedRescalerInfo<char, short>;
533  extern template class DefaultedRescalerInfo<unsigned long, short>;
534  extern template class DefaultedRescalerInfo<long, short>;
535 }
536 
537 #endif
RescalerInfo()
Construct object requesting default rescaling.
RescalerInfo _info
Definition: converter.h:247
void convert(const INP &in, OUTP &out) const
Definition: converter.h:317
bool explicitRescale() const
Test if any explicit rescaling parameters has been specified.
Mid-level converter.
Definition: converter.h:205
This converter is a bit higher-level than RawConverter and Rescaler, it switches to the one or the ot...
Definition: converter.h:158
STL namespace.
virtual void convert(const INP &in, OUTP &out) const
Converts INP into an existing OUTP object.
Definition: converter.h:339
ShallowConverter(bool rescale=false)
Definition: converter.h:260
OUTP getScaledValue(INP value) const
Definition: converter.h:431
ConverterSwitch(const RescalerInfo &info)
Definition: converter.h:176
Low level rescaler info used for rescaling.
Definition: converter.h:57
TYPE getcheckedmax(double max)
Definition: converter.h:420
Converter(bool rescale=false)
Definition: converter.h:223
void convert(const INP &, Void &) const
Definition: converter.h:101
#define CARTO_SPECIALIZED_RAWCONVERTER_ROUNDED_CONVERT(INP, OUTP)
Definition: converter.h:290
static _Tp min()
Definition: limits_gcc3.h:991
Low-level rescaling converter.
Definition: converter.h:142
void convert(const Void &, Void &) const
Definition: converter.h:111
void convert(const Void &, OUTP &out) const
Definition: converter.h:90
T min_limit()
Definition: converter.h:389
OUTP * operator()(const INP &in) const
Converts an INP type data to an OUTP data.
Definition: converter.h:330
static OUTP * alloc(const INP &in)
Definition: converter.h:323
This allocator is used by the top-level Converter to allocate a new object depending on the input: it...
Definition: converter.h:164
virtual ~Converter()
Definition: converter.h:226
TYPE getcheckedmin(double min)
Definition: converter.h:413
Converter(bool rescale, const RescalerInfo &info)
Definition: converter.h:224
bool usevtypelimits
Use limits of the input type instead of effective input min-max.
Definition: converter.h:69
Void does not contain anything.
Definition: types.h:60
bool ismax_limit(T value)
Definition: converter.h:401
ShallowConverter(bool rescale, RescalerInfo &info)
Definition: converter.h:262
Low-level raw converter (not rescaling)
Definition: converter.h:79
SmartConverter(const RescalerInfo &info)
Definition: converter.h:211
void convert(const INP &in, OUTP &out) const
Definition: converter.h:282
High-level converter, reimplementation of aims::Converter.
Definition: converter.h:220
bool ismin_limit(T value)
Definition: converter.h:396
bool isvalidvalue(TYPE value)
Definition: converter.h:406
ShallowConverter only differs from the "standard" Converter in the way that it may make shallow copie...
Definition: converter.h:257
static _Tp max()
Definition: limits_gcc3.h:992