CCfits 2.7
KeywordT.h
1// Astrophysics Science Division,
2// NASA/ Goddard Space Flight Center
3// HEASARC
4// http://heasarc.gsfc.nasa.gov
5// e-mail: ccfits@legacy.gsfc.nasa.gov
6//
7// Original author: Ben Dorman
8
9#ifndef KEYWORDT_H
10#define KEYWORDT_H
11#include "KeyData.h"
12#include "HDU.h"
13#include <typeinfo>
14#include <sstream>
15
16#ifdef _MSC_VER
17#include "MSconfig.h"
18#endif
19
20// contains definitions of templated member functions for Keyword. This separate
21// file organization is necessary to break cyclic dependency of Keyword on its
22// subclass, KeyData.
23
24
25namespace CCfits
26{
27
28 template <typename T>
29 T& Keyword::value (T& val) const
30 {
31 try
32 {
33 const KeyData<T>& thisKey = dynamic_cast<const KeyData<T>&>(*this);
34 val = thisKey.keyval();
35 }
36 catch (std::bad_cast&)
37 {
38 throw Keyword::WrongKeywordValueType(name());
39 }
40 return val;
41 }
42
43 template <typename T>
44 void Keyword::setValue (const T& newValue)
45 {
46 try
47 {
48 KeyData<T>& thisKey = dynamic_cast<KeyData<T>&>(*this);
49 thisKey.keyval(newValue);
50 thisKey.write();
51 }
52 catch (std::bad_cast&)
53 {
54 throw Keyword::WrongKeywordValueType(name());
55 }
56 }
57
58#if SPEC_TEMPLATE_IMP_DEFECT || SPEC_TEMPLATE_DECL_DEFECT
59 template<>
60 inline double& Keyword::value(double& val) const
61 {
62 switch (m_keytype)
63 {
64 case Tint:
65 {
66 const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
67 val = thisKey.keyval();
68 }
69 break;
70 case Tfloat:
71 {
72 const KeyData<float>& thisKey = static_cast<const KeyData<float>&>(*this);
73 val = thisKey.keyval();
74 }
75 break;
76 case Tdouble:
77 {
78 // Note: if val is of type float some precision will be lost here,
79 // but allow anyway. Presumably the user doesn't mind or they
80 // wouldn't be using single precision.
81 const KeyData<double>& thisKey = static_cast<const KeyData<double>&>(*this);
82 val = thisKey.keyval();
83 }
84 break;
85 case Tstring:
86 {
87 // Allow only if string can be converted to an integer.
88 const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this);
89 std::istringstream testStream(thisKey.keyval());
90 int stringInt = 0;
91 if (!(testStream >> stringInt) || !testStream.eof())
92 {
93 throw Keyword::WrongKeywordValueType(name());
94 }
95 val = stringInt;
96 }
97 break;
98 default:
99 throw Keyword::WrongKeywordValueType(name());
100 break;
101 }
102 return val;
103 }
104
105 // NOTE: This function actually instantiates Keyword::value<double>
106 // and therefore must be defined AFTER the specialized
107 // definition/declaration.
108 template<>
109 inline float& Keyword::value(float& val) const
110 {
111 double dval=.0;
112 val = static_cast<float>(value(dval));
113 return val;
114 }
115
116 template <>
117 inline int& Keyword::value(int& val) const
118 {
119 if (m_keytype == Tstring)
120 {
121 // Allow only if string can be converted to an integer.
122 const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this);
123 std::istringstream testStream(thisKey.keyval());
124 int stringInt = 0;
125 if (!(testStream >> stringInt) || !testStream.eof())
126 {
127 throw Keyword::WrongKeywordValueType(name());
128 }
129 val = stringInt;
130 }
131 else if (m_keytype == Tint)
132 {
133 const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
134 val = thisKey.keyval();
135 }
136 else
137 {
138 throw Keyword::WrongKeywordValueType(name());
139 }
140 return val;
141 }
142
143 template <>
144 inline String& Keyword::value(String& val) const
145 {
146 switch (m_keytype)
147 {
148 case Tint:
149 {
150 const KeyData<int>& thisKey = static_cast<const KeyData<int>&>(*this);
151 std::ostringstream oss;
152 oss << thisKey.keyval();
153 val = oss.str();
154 }
155 break;
156 case Tfloat:
157 {
158 const KeyData<float>& thisKey = static_cast<const KeyData<float>&>(*this);
159 std::ostringstream oss;
160 oss << thisKey.keyval();
161 val = oss.str();
162 }
163 break;
164 case Tdouble:
165 {
166 const KeyData<double>& thisKey = static_cast<const KeyData<double>&>(*this);
167 std::ostringstream oss;
168 oss << thisKey.keyval();
169 val = oss.str();
170 }
171 break;
172 case Tstring:
173 {
174 const KeyData<String>& thisKey = static_cast<const KeyData<String>&>(*this);
175 val = thisKey.keyval();
176 }
177 break;
178 default:
179 throw Keyword::WrongKeywordValueType(name());
180 }
181 return val;
182 }
183
184
185 template <>
186 inline void Keyword::setValue(const float& newValue)
187 {
188 if (m_keytype == Tfloat)
189 {
190 KeyData<float>& thisKey = static_cast<KeyData<float>&>(*this);
191 thisKey.keyval(newValue);
192 thisKey.write();
193 }
194 else if (m_keytype == Tdouble)
195 {
196 KeyData<double>& thisKey = static_cast<KeyData<double>&>(*this);
197 thisKey.keyval(static_cast<double>(newValue));
198 thisKey.write();
199 }
200 else
201 {
202 throw Keyword::WrongKeywordValueType(name());
203 }
204 }
205
206 template <>
207 inline void Keyword::setValue(const double& newValue)
208 {
209 if (m_keytype == Tdouble)
210 {
211 KeyData<double>& thisKey = static_cast<KeyData<double>&>(*this);
212 thisKey.keyval(newValue);
213 thisKey.write();
214 }
215 else if (m_keytype == Tfloat)
216 {
217 // This will lose precision but allow it anyway.
218 KeyData<float>& thisKey = static_cast<KeyData<float>&>(*this);
219 thisKey.keyval(static_cast<float>(newValue));
220 thisKey.write();
221 }
222 else
223 {
224 throw Keyword::WrongKeywordValueType(name());
225 }
226
227 }
228
229 template <>
230 inline void Keyword::setValue(const int& newValue)
231 {
232 if (m_keytype == Tint)
233 {
234 KeyData<int>& thisKey = static_cast<KeyData<int>&>(*this);
235 thisKey.keyval(newValue);
236 thisKey.write();
237 }
238 else if (m_keytype == Tfloat)
239 {
240 KeyData<float>& thisKey = static_cast<KeyData<float>&>(*this);
241 thisKey.keyval(static_cast<float>(newValue));
242 thisKey.write();
243 }
244 else if (m_keytype == Tdouble)
245 {
246 KeyData<double>& thisKey = static_cast<KeyData<double>&>(*this);
247 thisKey.keyval(static_cast<double>(newValue));
248 thisKey.write();
249 }
250 else if (m_keytype == Tstring)
251 {
252 KeyData<String>& thisKey = static_cast<KeyData<String>&>(*this);
253 std::ostringstream oss;
254 oss << newValue;
255 thisKey.keyval(oss.str());
256 thisKey.write();
257 }
258 else
259 {
260 throw Keyword::WrongKeywordValueType(name());
261 }
262
263 }
264
265
266
267#endif
268} // namespace CCfits
269
270#endif
T & value(T &val) const
get the keyword value
Definition KeywordT.h:29
const String & name() const
return the name of a keyword
Definition Keyword.h:322
void setValue(const T &newValue)
modify the value of an existing Keyword and write it to the file
Definition KeywordT.h:44
Namespace enclosing all CCfits classes and globals definitions.
Definition AsciiTable.cxx:26