source: XIOS/trunk/src/type/enum_ref_impl.hpp @ 1105

Last change on this file since 1105 was 1105, checked in by mhnguyen, 7 years ago

Adding comparison operator between objects of XIOS.
Two objects of a same type are considered equal if they have same non-empty
attributes which have same values

+) Add operator== to class CArray
+) Add comparison operator to some basic attribute classes
+) Add operator== to date and duration (It seems that they don't serve much)

Test
+) On Curie
+) No Unit tests but test with transformation work (the next commit)

  • 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  }
239 
240  template <typename T>
241  size_t CEnum_ref<T>::_size(void) const
242  {
243    return sizeof(T_enum) ;
244  }
245 
246  template <typename T>
247  bool CEnum_ref<T>::_isEmpty(void) const
248  {
249    return empty ;
250  }
251   
252  template <typename T>
253  void CEnum_ref<T>::_reset(void)
254  {
255      empty=true ;
256  }
257 
258  template <typename T>
259  void CEnum_ref<T>::checkEmpty(void) const
260  {
261    if (empty) ERROR("template <typename T> void CEnum_ref<T>::checkEmpty(void)",
262                     << "Enum reference is not initialized.") ;
263  }
264                     
265  template <typename T> 
266  bool operator== (const CEnum_ref<T>& lhs, const typename T::t_enum& rhs)
267  {
268     if (lhs.isEmpty()) return false;
269     return (lhs.get() == rhs);
270  }
271
272  template <typename T> 
273  bool operator== (const typename T::t_enum& lhs, const CEnum_ref<T>& rhs)
274  {
275    return rhs == lhs;
276  }
277
278  template <typename T> 
279  bool operator== (const CEnum_ref<T>& lhs, const CEnum_ref<T>& rhs)
280  {
281    if ((lhs.isEmpty() && !rhs.isEmpty()) || (!lhs.isEmpty() && rhs.isEmpty())) return false;
282    if (lhs.isEmpty() && rhs.isEmpty()) return true;
283    return (lhs.get() == rhs.get());
284  }
285 
286  template <typename T>
287  CBufferOut& operator<<(CBufferOut& buffer, const CEnum_ref<T>& type)
288  {
289    if (!type.toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const CEnum_ref<T>& type)",
290                                      << "Not enough free space in buffer to queue the enum.");
291    return buffer ;
292  }
293
294  template <typename T>
295  CBufferOut& operator<<(CBufferOut& buffer, typename T::t_enum& type)
296  {
297    if (!CEnum_ref<T>(type).toBuffer(buffer)) ERROR("template <typename T> CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum& type)",
298                                                    << "Not enough free space in buffer to queue the enum.");
299    return buffer ;
300  }
301
302  template <typename T>
303  CBufferIn& operator>>(CBufferIn& buffer, typename T::t_enum& type)
304  {
305    if (!CEnum_ref<T>(type).fromBuffer(buffer)) ERROR("template <typename T>  CBufferIn& operator>>(CBufferIn& buffer, typename T::t_enum& type)",
306                                                      << "Not enough data in buffer to unqueue the enum.");
307    return buffer ;
308  }
309
310  template <typename T>
311  CBufferIn& operator>>(CBufferIn& buffer, const CEnum_ref<T>& type)
312  {
313    if (!type.fromBuffer(buffer)) ERROR("template <typename T> CBufferIn& operator>>(CBufferIn& buffer, const CEnum_ref<T>& type) ",
314                                        << "Not enough data in buffer to unqueue the enum.");
315    return buffer ;
316    return buffer ;
317  }
318
319
320/*
321  template <typename T>
322  CMessage& operator<<(CMessage& msg, const CEnum_ref<T>& type)
323  {
324    msg.push(*type.clone()) ;
325    return msg ;
326  }
327*/
328
329  template <typename T>
330  CMessage& operator<<(CMessage& msg, typename T::t_enum & type)
331  {
332    msg.push(*CEnum_ref<T>(type).clone()) ;
333    return msg ;
334  }
335 
336}
337
338#endif
339
Note: See TracBrowser for help on using the repository browser.