CCfits: KeywordT.h Source File

CCfits 2.7

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List

KeywordT.h

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