File indexing completed on 2024-12-29 04:11:45

0001 /***************************************************************************
0002  *                                                                         *
0003  *   Copyright : (C) 2010 The University of Toronto                        *
0004  *   email     : netterfield@astro.utoronto.ca                             *
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  ***************************************************************************/
0012 
0013 #ifndef KST_ATOF_H
0014 #define KST_ATOF_H
0015 
0016 #include <QByteArray>
0017 #include <QString>
0018 #include <stdlib.h>
0019 
0020 #include "math_kst.h"
0021 
0022 #ifdef Q_CC_MSVC
0023   #define KST_THREAD_LOCAL __declspec(thread)
0024 #else
0025  #ifndef KST_NO_THREAD_LOCAL
0026    #define KST_THREAD_LOCAL __thread
0027   #else
0028    #define KST_THREAD_LOCAL
0029   #endif
0030 #endif
0031 
0032 class LexicalCast
0033 {
0034 public:
0035 
0036   static LexicalCast& instance();
0037 
0038 
0039   enum NaNMode {
0040     NullValue,
0041     NaNValue,
0042     PreviousValue
0043   };
0044 
0045   struct AutoReset {
0046     AutoReset(bool useDot, NaNMode);
0047     ~AutoReset();
0048   };
0049 
0050   void setUseDotAsDecimalSeparator(bool useDot);
0051 
0052   char localSeparator() const;
0053 
0054 #ifdef KST_USE_KST_ATOF
0055   double fromDouble(const char* p) const;
0056 #else
0057   inline double fromDouble(const char* p) const { return atof(p); }
0058 #endif
0059   double fromTime(const char*) const;
0060   inline double toDouble(const char* p) const { return _isFormattedTime ? fromTime(p) : fromDouble(p); }
0061 
0062   void setTimeFormat(const QString& format);
0063   
0064   double nanValue() const;
0065 
0066 private:
0067   LexicalCast();
0068   ~LexicalCast();
0069 
0070   NaNMode _nanMode;
0071   static KST_THREAD_LOCAL double _previousValue;
0072   char _separator;
0073 
0074   QByteArray _originalLocal;
0075   QString _timeFormat;
0076   int _timeFormatLength;
0077   bool _isFormattedTime;
0078   bool _timeWithDate;
0079 
0080   void resetLocal();
0081 
0082   inline bool isDigit(const char c) const {
0083     return (c >= 48) && (c <= 57) ? true : false;
0084   }
0085 };
0086 
0087 
0088 //-------------------------------------------------------------------------------------------
0089 inline double LexicalCast::nanValue() const
0090 {
0091   switch (_nanMode) {
0092   case NullValue:     return 0;
0093   case NaNValue:      return Kst::NOPOINT;
0094   case PreviousValue: return _previousValue;
0095   default:            return 0;
0096   }
0097 }
0098 
0099 
0100 #endif
0101 
0102 // vim: ts=2 sw=2 et