KeywordT.h

00001 
00002 //      This is version 1.6 release dated Nov 2006
00003 
00004 //      Astrophysics Science Division,
00005 //      NASA/ Goddard Space Flight Center
00006 //      HEASARC
00007 //      http://heasarc.gsfc.nasa.gov
00008 //      e-mail: ccfits@legacy.gsfc.nasa.gov
00009 //
00010 //      Original author: Ben Dorman, L3-Communications EER Systems Inc.
00011 
00012 #ifndef KEYWORDT_H
00013 #define KEYWORDT_H
00014 #include "KeyData.h"
00015 #include "HDU.h"
00016 #include <typeinfo>
00017 #include <sstream>
00018 
00019 #ifdef _MSC_VER
00020 #include "MSconfig.h"
00021 #endif
00022 
00023 // contains definitions of templated member functions for Keyword. This separate
00024 // file organization is necessary to break cyclic dependency of Keyword on its
00025 // subclass, KeyData.
00026 
00027 
00028 namespace CCfits 
00029 {
00030 
00031    template <typename T>
00032    T& Keyword::value (T& val) const
00033    {
00034       try
00035       {
00036             const KeyData<T>& thisKey = dynamic_cast<const KeyData<T>&>(*this);
00037             val = thisKey.keyval();
00038       }
00039       catch (std::bad_cast)
00040       {
00041          throw Keyword::WrongKeywordValueType(name());
00042       }
00043       return val;
00044    }
00045 
00046    template <typename T>
00047    void Keyword::setValue (const T& newValue)
00048    {
00049            try
00050            {
00051                    KeyData<T>& thisKey = dynamic_cast<KeyData<T>&>(*this);
00052                    thisKey.keyval(newValue);
00053            }
00054            catch (std::bad_cast)
00055            {
00056                    throw Keyword::WrongKeywordValueType(name());
00057            }
00058 
00059    }
00060 
00061 #if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
00062    template<>
00063    inline double& Keyword::value(double& val) const
00064    {
00065       switch (m_keytype)
00066       {
00067          case Tint:
00068             {
00069                const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
00070                val = thisKey.keyval();
00071             }
00072             break;
00073          case Tfloat:
00074             {
00075                const KeyData<float>& thisKey = static_cast<const KeyData<float>&>(*this);
00076                val = thisKey.keyval();
00077             }
00078             break;
00079          case Tdouble:
00080             {
00081                // Note: if val is of type float some precision will be lost here,
00082                // but allow anyway.  Presumably the user doesn't mind or they
00083                // wouldn't be using single precision.
00084                const KeyData<double>& thisKey = static_cast<const KeyData<double>&>(*this);
00085                val = thisKey.keyval();
00086             }
00087             break;
00088          case Tstring:
00089             {
00090                // Allow only if string can be converted to an integer.
00091                const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this); 
00092                std::istringstream testStream(thisKey.keyval());
00093                int stringInt = 0;
00094                if (!(testStream >> stringInt) || !testStream.eof())
00095                {
00096                   throw Keyword::WrongKeywordValueType(name());
00097                }
00098                val = stringInt;
00099             }
00100             break;
00101          default:
00102             throw Keyword::WrongKeywordValueType(name());
00103             break;
00104       }
00105       return val;
00106    }
00107 
00108    // NOTE: This function actually instantiates Keyword::value<double>
00109    // and therefore must be defined AFTER the specialized 
00110    // definition/declaration.
00111    template<>
00112    inline float& Keyword::value(float& val) const
00113    {
00114       double dval=.0;
00115       val = static_cast<float>(value(dval));
00116       return val;
00117    }
00118 
00119    template <>
00120    inline int& Keyword::value(int& val) const
00121    {
00122          if (m_keytype == Tstring)
00123          {
00124             // Allow only if string can be converted to an integer.
00125             const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this); 
00126             std::istringstream testStream(thisKey.keyval());
00127             int stringInt = 0;
00128             if (!(testStream >> stringInt) || !testStream.eof())
00129             {
00130                throw Keyword::WrongKeywordValueType(name());
00131             }
00132             val = stringInt;         
00133          } 
00134          else if (m_keytype == Tint)
00135          {
00136             const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
00137             val = thisKey.keyval();
00138          } 
00139          else
00140          {
00141             throw Keyword::WrongKeywordValueType(name());
00142          }
00143          return val;    
00144    }
00145 #endif
00146 } // namespace CCfits
00147 
00148 #endif

Generated on Fri Nov 3 17:09:05 2006 for CCfits by  doxygen 1.4.7