source: XIOS/branchs/xios-2.5/src/type/enum_ref_impl.hpp @ 1850

Last change on this file since 1850 was 1850, checked in by ymipsl, 4 years ago

Compiler fix : solve the problem of crash occured with recent version of GCC, only in optimised mode > O1
It seems to be due to non return value from a non void function in case of early initialization (static initialization).
Thanks to A. Durocher who find the tip.

YM

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 8.2 KB
Line 
1#ifndef __XIOS_ENUM_REF_IMPL__
2#define __XIOS_ENUM_REF_IMPL__
3
4#include "xios_spl.hpp"
5#include "exception.hpp"
6#include "buffer_in.hpp"
7#include "buffer_out.hpp"
8#include "message.hpp"
9#include <string>
10#include <boost/algorithm/string.hpp>
11
12namespace xios
13{
14 
15   
16  using namespace std;
17 
18  template <typename T>
19  CEnum_ref<T>::CEnum_ref(void)
20  {
21    empty=true ;
22  }
23   
24  template <typename T>
25  CEnum_ref<T>::CEnum_ref(T_enum& val)
26  {
27    empty=true ;
28    set_ref(val) ;
29  }
30 
31  template <typename T>
32  CEnum_ref<T>::CEnum_ref(CEnum<T>& type)
33  {
34    empty=true ;
35    set_ref(type) ;
36  }
37
38  template <typename T>
39  CEnum_ref<T>::CEnum_ref(const CEnum_ref<T>& type)
40  {
41    empty=true ;
42    set_ref(type) ;
43  } 
44
45 
46  template <typename T>
47  void CEnum_ref<T>::set_ref(T_enum& val)
48  {
49    ptrValue=&val ;
50    empty=false ;
51  }
52
53  template <typename T>
54  void CEnum_ref<T>::set_ref(CEnum<T>& type)
55  {
56    ptrValue=&type.get() ;
57    empty=false ;
58  }
59
60  template <typename T>
61  void CEnum_ref<T>::set_ref(const CEnum_ref<T>& type)
62  {
63    ptrValue=type.ptrValue ;
64    empty=type.empty ;
65  }
66
67  template <typename T>
68  void CEnum_ref<T>::set(const T_enum& val) const
69  {
70    checkEmpty() ;
71    *ptrValue=val ;
72  }
73
74  template <typename T>
75  void CEnum_ref<T>::set(const CEnum<T>& type) const
76  {
77    checkEmpty() ;
78    *ptrValue=type.get() ;
79  }
80
81  template <typename T>
82  void CEnum_ref<T>::set(const CEnum_ref<T>& type) const
83  {
84    checkEmpty() ;
85    *ptrValue=type.get() ;
86  }
87 
88  template <typename T>
89  typename T::t_enum & CEnum_ref<T>::get(void) const
90  {
91    checkEmpty() ;
92    return *ptrValue ;
93  }
94 
95  template <typename T>
96  const CEnum_ref<T>& CEnum_ref<T>::operator = (T_enum& val) const
97  {
98    set(val) ;
99    return *this ;
100  }
101
102  template <typename T>
103  const CEnum_ref<T>& CEnum_ref<T>::operator = (CEnum<T>& type) const
104  {
105    set(type) ;
106    return *this ;
107  }
108   
109  template <typename T>
110  const CEnum_ref<T>& CEnum_ref<T>::operator = (const CEnum_ref<T>& type) const
111  {
112    set(type) ;
113    return *this ;
114  }
115 
116  template <typename T>
117  CEnum_ref<T>::operator T_enum&() const
118  {
119    checkEmpty() ;
120    return *ptrValue ;
121  }
122
123  template <typename T>
124  CEnum_ref<T>* CEnum_ref<T>::_clone(void) const
125  {
126    checkEmpty() ;
127    return new CEnum_ref<T>(*this) ;
128  }
129   
130  template <typename T>
131  void CEnum_ref<T>::_fromString(const string& str) const
132  {
133    istringstream iss(str);
134    checkEmpty() ;
135    iss>>*ptrValue ;
136  }
137 
138  template <typename T>
139  void CEnum_ref<T>::_fromString(const string& str)
140  {
141    checkEmpty() ;
142    string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ;
143   
144    bool found=false ;
145    for(int i=0;i<T::getSize();i++)
146    {
147      if (boost::to_lower_copy(string(T::getStr()[i]))==tmpStr)
148      {
149        *ptrValue=(T_enum) i ;
150        return ;
151      }
152    }
153   
154    ostringstream strList ;
155    for(int i=0;i<T::getSize();i++) 
156    {
157      if (i>0) strList<<", " ;
158      strList<<boost::to_lower_copy(string(T::getStr()[i])) ;
159    }
160   
161    ERROR("template <typename T> void CEnum_ref<T>::_fromString(const string& str)",
162          << tmpStr << " cannot be converted in a valid enumeration, possibilities are: " << strList.str());
163  }
164 
165  template <typename T>
166  string CEnum_ref<T>::_toString(void) const
167  {
168    if (empty) return string("empty"); 
169    return string((T::getStr())[(int)(*ptrValue)]) ;
170  }
171
172   
173  template <typename T>
174  bool CEnum_ref<T>::_toBuffer(CBufferOut& buffer) const
175  {
176    checkEmpty() ;
177    if (sizeof(*ptrValue)==sizeof(short int)) return buffer.put((short int) *ptrValue) ;
178    else if (sizeof(*ptrValue)==sizeof(int)) return buffer.put((int) *ptrValue) ;
179    else if (sizeof(*ptrValue)==sizeof(long int)) return buffer.put((long int) *ptrValue) ;
180    else ERROR("template <typename T> bool CEnum_ref<T>::_toBuffer(CBufferOut& buffer) const",
181               << "incompatibility between enumeration and standard integer type.");
182    return false ;
183  }
184 
185  template <typename T>
186  bool CEnum_ref<T>::_fromBuffer(CBufferIn& buffer)
187  {
188    checkEmpty() ;
189    bool ret ;
190    if (sizeof(*ptrValue)==sizeof(short int)) 
191    {
192      short int val ;
193      ret=buffer.get(val) ;
194      if (ret) *ptrValue = (T_enum) val ;
195    }
196    else if (sizeof(*ptrValue)==sizeof(int)) 
197    {
198      int val ;
199      ret=buffer.get(val) ;
200      if (ret) *ptrValue = (T_enum) val ;
201    }
202    else if (sizeof(*ptrValue)==sizeof(long int)) 
203    {
204      long int val ;
205      ret=buffer.get(val) ;
206      if (ret) *ptrValue = (T_enum) val ;
207    }
208    else ERROR("template <typename T> bool CEnum_ref<T>::_fromBuffer(CBufferIn& buffer)",
209               << "incompatibility between enumeration and standard integer type.");
210    return ret ;
211  }
212 
213  template <typename T>
214  bool CEnum_ref<T>::_fromBuffer(CBufferIn& buffer) const
215  {
216    checkEmpty() ;
217    bool ret ;
218    if (sizeof(*ptrValue)==sizeof(short int)) 
219    {
220      short int val ;
221      ret=buffer.get(val) ;
222      if (ret) *ptrValue = (T_enum) val ;
223    }
224    else if (sizeof(*ptrValue)==sizeof(int)) 
225    {
226      int val ;
227      ret=buffer.get(val) ;
228      if (ret) *ptrValue = (T_enum) val ;
229    }
230    else if (sizeof(*ptrValue)==sizeof(long int)) 
231    {
232      long int val ;
233      ret=buffer.get(val) ;
234      if (ret) *ptrValue = (T_enum) val ;
235    }
236    else ERROR("template <typename T> bool CEnum_ref<T>::_fromBuffer(CBufferIn& buffer)",
237               << "incompatibility between enumeration and standard integer type");
238    return ret ;
239  }
240 
241  template <typename T>
242  size_t CEnum_ref<T>::_size(void) const
243  {
244    return sizeof(T_enum) ;
245  }
246 
247  template <typename T>
248  bool CEnum_ref<T>::_isEmpty(void) const
249  {
250    return empty ;
251  }
252   
253  template <typename T>
254  void CEnum_ref<T>::_reset(void)
255  {
256      empty=true ;
257  }
258 
259  template <typename T>
260  void CEnum_ref<T>::checkEmpty(void) const
261  {
262    if (empty) ERROR("template <typename T> void CEnum_ref<T>::checkEmpty(void)",
263                     << "Enum reference is not initialized.") ;
264  }
265                     
266  template <typename T> 
267  bool operator== (const CEnum_ref<T>& lhs, const typename T::t_enum& rhs)
268  {
269     if (lhs.isEmpty()) return false;
270     return (lhs.get() == rhs);
271  }
272
273  template <typename T> 
274  bool operator== (const typename T::t_enum& lhs, const CEnum_ref<T>& rhs)
275  {
276    return rhs == lhs;
277  }
278
279  template <typename T> 
280  bool operator== (const CEnum_ref<T>& lhs, const CEnum_ref<T>& rhs)
281  {
282    if ((lhs.isEmpty() && !rhs.isEmpty()) || (!lhs.isEmpty() && rhs.isEmpty())) return false;
283    if (lhs.isEmpty() && rhs.isEmpty()) return true;
284    return (lhs.get() == rhs.get());
285  }
286 
287  template <typename T>
288  CBufferOut& operator<<(CBufferOut& buffer, const CEnum_ref<T>& type)
289  {
290    if (!type.toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const CEnum_ref<T>& type)",
291                                      << "Not enough free space in buffer to queue the enum.");
292    return buffer ;
293  }
294
295  template <typename T>
296  CBufferOut& operator<<(CBufferOut& buffer, typename T::t_enum& type)
297  {
298    if (!CEnum_ref<T>(type).toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum& type)",
299                                                    << "Not enough free space in buffer to queue the enum.");
300    return buffer ;
301  }
302
303  template <typename T>
304  CBufferIn& operator>>(CBufferIn& buffer, typename T::t_enum& type)
305  {
306    if (!CEnum_ref<T>(type).fromBuffer(buffer)) ERROR("template <typename T>  CBufferIn& operator>>(CBufferIn& buffer, typename T::t_enum& type)",
307                                                      << "Not enough data in buffer to unqueue the enum.");
308    return buffer ;
309  }
310
311  template <typename T>
312  CBufferIn& operator>>(CBufferIn& buffer, const CEnum_ref<T>& type)
313  {
314    if (!type.fromBuffer(buffer)) ERROR("template <typename T> CBufferIn& operator>>(CBufferIn& buffer, const CEnum_ref<T>& type) ",
315                                        << "Not enough data in buffer to unqueue the enum.");
316    return buffer ;
317    return buffer ;
318  }
319
320
321/*
322  template <typename T>
323  CMessage& operator<<(CMessage& msg, const CEnum_ref<T>& type)
324  {
325    msg.push(*type.clone()) ;
326    return msg ;
327  }
328*/
329
330  template <typename T>
331  CMessage& operator<<(CMessage& msg, typename T::t_enum & type)
332  {
333    msg.push(*CEnum_ref<T>(type).clone()) ;
334    return msg ;
335  }
336 
337}
338
339#endif
340
Note: See TracBrowser for help on using the repository browser.