KeywordT.h

00001 //1
00002 //2
00003 //3
00004 //4
00005 
00006 //      This is version 2.0 release dated Jan 2008
00007 
00008 //      Astrophysics Science Division,
00009 //      NASA/ Goddard Space Flight Center
00010 //      HEASARC
00011 //      http://heasarc.gsfc.nasa.gov
00012 //      e-mail: ccfits@legacy.gsfc.nasa.gov
00013 //
00014 //      Original author: Ben Dorman
00015 
00016 #ifndef KEYWORDT_H
00017 #define KEYWORDT_H
00018 #include "KeyData.h"
00019 #include "HDU.h"
00020 #include <typeinfo>
00021 #include <sstream>
00022 
00023 #ifdef _MSC_VER
00024 #include "MSconfig.h"
00025 #endif
00026 
00027 // contains definitions of templated member functions for Keyword. This separate
00028 // file organization is necessary to break cyclic dependency of Keyword on its
00029 // subclass, KeyData.
00030 
00031 
00032 namespace CCfits 
00033 {
00034 
00035    template <typename T>
00036    T& Keyword::value (T& val) const
00037    {
00038       try
00039       {
00040             const KeyData<T>& thisKey = dynamic_cast<const KeyData<T>&>(*this);
00041             val = thisKey.keyval();
00042       }
00043       catch (std::bad_cast)
00044       {
00045          throw Keyword::WrongKeywordValueType(name());
00046       }
00047       return val;
00048    }
00049 
00050    template <typename T>
00051    void Keyword::setValue (const T& newValue)
00052    {
00053            try
00054            {
00055                    KeyData<T>& thisKey = dynamic_cast<KeyData<T>&>(*this);
00056                    thisKey.keyval(newValue);
00057                    thisKey.write();
00058            }
00059            catch (std::bad_cast)
00060            {
00061                    throw Keyword::WrongKeywordValueType(name());
00062            }
00063 
00064    }
00065 
00066 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00067    template<>
00068    inline double& Keyword::value(double& val) const
00069    {
00070       switch (m_keytype)
00071       {
00072          case Tint:
00073             {
00074                const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
00075                val = thisKey.keyval();
00076             }
00077             break;
00078          case Tfloat:
00079             {
00080                const KeyData<float>& thisKey = static_cast<const KeyData<float>&>(*this);
00081                val = thisKey.keyval();
00082             }
00083             break;
00084          case Tdouble:
00085             {
00086                // Note: if val is of type float some precision will be lost here,
00087                // but allow anyway.  Presumably the user doesn't mind or they
00088                // wouldn't be using single precision.
00089                const KeyData<double>& thisKey = static_cast<const KeyData<double>&>(*this);
00090                val = thisKey.keyval();
00091             }
00092             break;
00093          case Tstring:
00094             {
00095                // Allow only if string can be converted to an integer.
00096                const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this); 
00097                std::istringstream testStream(thisKey.keyval());
00098                int stringInt = 0;
00099                if (!(testStream >> stringInt) || !testStream.eof())
00100                {
00101                   throw Keyword::WrongKeywordValueType(name());
00102                }
00103                val = stringInt;
00104             }
00105             break;
00106          default:
00107             throw Keyword::WrongKeywordValueType(name());
00108             break;
00109       }
00110       return val;
00111    }
00112 
00113    // NOTE: This function actually instantiates Keyword::value<double>
00114    // and therefore must be defined AFTER the specialized 
00115    // definition/declaration.
00116    template<>
00117    inline float& Keyword::value(float& val) const
00118    {
00119       double dval=.0;
00120       val = static_cast<float>(value(dval));
00121       return val;
00122    }
00123 
00124    template <>
00125    inline int& Keyword::value(int& val) const
00126    {
00127          if (m_keytype == Tstring)
00128          {
00129             // Allow only if string can be converted to an integer.
00130             const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this); 
00131             std::istringstream testStream(thisKey.keyval());
00132             int stringInt = 0;
00133             if (!(testStream >> stringInt) || !testStream.eof())
00134             {
00135                throw Keyword::WrongKeywordValueType(name());
00136             }
00137             val = stringInt;         
00138          } 
00139          else if (m_keytype == Tint)
00140          {
00141             const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
00142             val = thisKey.keyval();
00143          } 
00144          else
00145          {
00146             throw Keyword::WrongKeywordValueType(name());
00147          }
00148          return val;    
00149    }
00150 
00151 
00152    template <>
00153    inline void Keyword::setValue(const float& newValue)
00154    {
00155       if (m_keytype == Tfloat)
00156       {
00157          KeyData<float>& thisKey = static_cast<KeyData<float>&>(*this);
00158          thisKey.keyval(newValue);
00159          thisKey.write();
00160       }
00161       else if (m_keytype == Tdouble)
00162       {
00163          KeyData<double>& thisKey = static_cast<KeyData<double>&>(*this);
00164          thisKey.keyval(static_cast<double>(newValue));
00165          thisKey.write();
00166       }
00167       else
00168       {
00169          throw Keyword::WrongKeywordValueType(name());
00170       }
00171    }
00172 
00173    template <>
00174    inline void Keyword::setValue(const double& newValue)
00175    {
00176       if (m_keytype == Tdouble)
00177       {
00178          KeyData<double>& thisKey = static_cast<KeyData<double>&>(*this);
00179          thisKey.keyval(newValue);
00180          thisKey.write();
00181       }
00182       else if (m_keytype == Tfloat)
00183       {
00184          // This will lose precision but allow it anyway.
00185          KeyData<float>& thisKey = static_cast<KeyData<float>&>(*this);
00186          thisKey.keyval(static_cast<float>(newValue));
00187          thisKey.write();
00188       }
00189       else
00190       {
00191          throw Keyword::WrongKeywordValueType(name());
00192       }
00193 
00194    }
00195 
00196    template <>
00197    inline void Keyword::setValue(const int& newValue)
00198    {
00199       if (m_keytype == Tint)
00200       {
00201          KeyData<int>& thisKey = static_cast<KeyData<int>&>(*this);
00202          thisKey.keyval(newValue);
00203          thisKey.write();
00204       }
00205       else if (m_keytype == Tfloat)
00206       {
00207          KeyData<float>& thisKey = static_cast<KeyData<float>&>(*this);
00208          thisKey.keyval(static_cast<float>(newValue));
00209          thisKey.write();
00210       }
00211       else if (m_keytype == Tdouble)
00212       {
00213          KeyData<double>& thisKey = static_cast<KeyData<double>&>(*this);
00214          thisKey.keyval(static_cast<double>(newValue));
00215          thisKey.write();
00216       }
00217       else if (m_keytype == Tstring)
00218       {
00219          KeyData<String>& thisKey = static_cast<KeyData<String>&>(*this);
00220          std::ostringstream oss;
00221          oss << newValue;
00222          thisKey.keyval(oss.str());
00223          thisKey.write();
00224       }
00225       else
00226       {
00227          throw Keyword::WrongKeywordValueType(name());
00228       }
00229 
00230    }
00231 
00232 #endif
00233 } // namespace CCfits
00234 
00235 #endif

Generated on Tue Feb 5 11:26:56 2008 for CCfits by  doxygen 1.5.4