KeywordT.h

00001 //1
00002 //2
00003 //3
00004 //4
00005 
00006 //      This is version 1.7 release dated June 2007
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, L3-Communications EER Systems Inc.
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            }
00058            catch (std::bad_cast)
00059            {
00060                    throw Keyword::WrongKeywordValueType(name());
00061            }
00062 
00063    }
00064 
00065 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00066    template<>
00067    inline double& Keyword::value(double& val) const
00068    {
00069       switch (m_keytype)
00070       {
00071          case Tint:
00072             {
00073                const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
00074                val = thisKey.keyval();
00075             }
00076             break;
00077          case Tfloat:
00078             {
00079                const KeyData<float>& thisKey = static_cast<const KeyData<float>&>(*this);
00080                val = thisKey.keyval();
00081             }
00082             break;
00083          case Tdouble:
00084             {
00085                // Note: if val is of type float some precision will be lost here,
00086                // but allow anyway.  Presumably the user doesn't mind or they
00087                // wouldn't be using single precision.
00088                const KeyData<double>& thisKey = static_cast<const KeyData<double>&>(*this);
00089                val = thisKey.keyval();
00090             }
00091             break;
00092          case Tstring:
00093             {
00094                // Allow only if string can be converted to an integer.
00095                const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this); 
00096                std::istringstream testStream(thisKey.keyval());
00097                int stringInt = 0;
00098                if (!(testStream >> stringInt) || !testStream.eof())
00099                {
00100                   throw Keyword::WrongKeywordValueType(name());
00101                }
00102                val = stringInt;
00103             }
00104             break;
00105          default:
00106             throw Keyword::WrongKeywordValueType(name());
00107             break;
00108       }
00109       return val;
00110    }
00111 
00112    // NOTE: This function actually instantiates Keyword::value<double>
00113    // and therefore must be defined AFTER the specialized 
00114    // definition/declaration.
00115    template<>
00116    inline float& Keyword::value(float& val) const
00117    {
00118       double dval=.0;
00119       val = static_cast<float>(value(dval));
00120       return val;
00121    }
00122 
00123    template <>
00124    inline int& Keyword::value(int& val) const
00125    {
00126          if (m_keytype == Tstring)
00127          {
00128             // Allow only if string can be converted to an integer.
00129             const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this); 
00130             std::istringstream testStream(thisKey.keyval());
00131             int stringInt = 0;
00132             if (!(testStream >> stringInt) || !testStream.eof())
00133             {
00134                throw Keyword::WrongKeywordValueType(name());
00135             }
00136             val = stringInt;         
00137          } 
00138          else if (m_keytype == Tint)
00139          {
00140             const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
00141             val = thisKey.keyval();
00142          } 
00143          else
00144          {
00145             throw Keyword::WrongKeywordValueType(name());
00146          }
00147          return val;    
00148    }
00149 #endif
00150 } // namespace CCfits
00151 
00152 #endif

Generated on Thu Jun 28 11:49:08 2007 for CCfits by  doxygen 1.4.7