PVData C++  8.0.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
typeCast.h
1 /*
2  * Copyright information and license terms for this software can be
3  * found in the file LICENSE that is included with the distribution
4  */
5 /* Author: Michael Davidsaver */
6 #ifndef PVTYPECAST_H
7 #define PVTYPECAST_H
8 
9 #include <stdexcept>
10 #include <sstream>
11 
12 #include <epicsConvert.h>
13 #include <shareLib.h>
14 
15 #include <pv/pvType.h>
16 #include <pv/pvIntrospect.h>
17 #include <pv/templateMeta.h>
18 
19 
20 namespace epics { namespace pvData {
21 
22 namespace detail {
23  // parseToPOD wraps the epicsParse*() functions in one name
24  // and throws exceptions
25  epicsShareExtern void parseToPOD(const char*, boolean *out);
26  epicsShareExtern void parseToPOD(const char*, int8 *out);
27  epicsShareExtern void parseToPOD(const char*, uint8 *out);
28  epicsShareExtern void parseToPOD(const char*, int16_t *out);
29  epicsShareExtern void parseToPOD(const char*, uint16_t *out);
30  epicsShareExtern void parseToPOD(const char*, int32_t *out);
31  epicsShareExtern void parseToPOD(const char*, uint32_t *out);
32  epicsShareExtern void parseToPOD(const char*, int64_t *out);
33  epicsShareExtern void parseToPOD(const char*, uint64_t *out);
34  epicsShareExtern void parseToPOD(const char*, float *out);
35  epicsShareExtern void parseToPOD(const char*, double *out);
36 
37  static inline void parseToPOD(const std::string& str, boolean *out) { return parseToPOD(str.c_str(), out); }
38  static inline void parseToPOD(const std::string& str, int8 *out) { return parseToPOD(str.c_str(), out); }
39  static inline void parseToPOD(const std::string& str, uint8 *out) { return parseToPOD(str.c_str(), out); }
40  static inline void parseToPOD(const std::string& str, int16_t *out) { return parseToPOD(str.c_str(), out); }
41  static inline void parseToPOD(const std::string& str, uint16_t *out) { return parseToPOD(str.c_str(), out); }
42  static inline void parseToPOD(const std::string& str, int32_t *out) { return parseToPOD(str.c_str(), out); }
43  static inline void parseToPOD(const std::string& str, uint32_t *out) { return parseToPOD(str.c_str(), out); }
44  static inline void parseToPOD(const std::string& str, int64_t *out) { return parseToPOD(str.c_str(), out); }
45  static inline void parseToPOD(const std::string& str, uint64_t *out) { return parseToPOD(str.c_str(), out); }
46  static inline void parseToPOD(const std::string& str, float *out) { return parseToPOD(str.c_str(), out); }
47  static inline void parseToPOD(const std::string& str, double *out) { return parseToPOD(str.c_str(), out); }
48 
49  /* want to pass POD types by value,
50  * and std::string by const reference
51  */
52  template<typename ARG>
53  struct cast_arg { typedef ARG arg; };
54  template<>
55  struct cast_arg<std::string> { typedef const std::string& arg; };
56 
57  // Handle mangling of type/value when printing
58  template<typename T>
59  struct print_convolute {
60  typedef T return_t;
61  static FORCE_INLINE return_t op(const T& i) { return i; }
62  };
63  // trick std::ostream into treating chars as numbers
64  // by promoting char to int
65  template<>
67  typedef signed int return_t;
68  static FORCE_INLINE return_t op(int8 i) { return i; }
69  };
70  template<>
72  typedef unsigned int return_t;
73  static FORCE_INLINE return_t op(uint8 i) { return i; }
74  };
75  // Turn boolean into a string
76  template<>
78  typedef const char* return_t;
79  static FORCE_INLINE return_t op(boolean i) { return i ? "true" : "false"; }
80  };
81 
82 
83  // default to C++ type casting
84  template<typename TO, typename FROM, class Enable = void>
85  struct cast_helper {
86  static FORCE_INLINE TO op(FROM from) {
87  return static_cast<TO>(from);
88  }
89  };
90 
91  // special handling when down-casting double to float
92  template<>
93  struct cast_helper<float, double> {
94  static FORCE_INLINE float op(double from) {
95  return epicsConvertDoubleToFloat(from);
96  }
97  };
98 
99  // print POD to string
100  // when std::string!=FROM
101  template<typename FROM>
102  struct cast_helper<std::string, FROM, typename meta::not_same_type<std::string,FROM>::type> {
103  static std::string op(FROM from) {
104  std::ostringstream strm;
105  strm << print_convolute<FROM>::op(from);
106  if(strm.fail())
107  throw std::runtime_error("Cast to string failed");
108  return strm.str();
109  }
110  };
111 
112  // parse POD from string
113  // TO!=std::string
114  template<typename TO>
115  struct cast_helper<TO, std::string, typename meta::not_same_type<TO,std::string>::type> {
116  static FORCE_INLINE TO op(const std::string& from) {
117  TO ret;
118  parseToPOD(from, &ret);
119  return ret;
120  }
121  };
122 
123  // parse POD from C string
124  // TO!=const char*
125  template<typename TO>
126  struct cast_helper<TO, const char*,
127  typename meta::_and<
130  >::type> {
131  static FORCE_INLINE TO op(const char* from) {
132  TO ret;
133  parseToPOD(from, &ret);
134  return ret;
135  }
136  };
137 
138 } // end detail
139 
194 template<typename TO, typename FROM>
195 static FORCE_INLINE TO castUnsafe(const FROM& from)
196 {
198 }
199 
200 epicsShareExtern void castUnsafeV(size_t count, ScalarType to, void *dest, ScalarType from, const void *src);
201 
206 template<typename T>
207 static FORCE_INLINE
208 typename detail::print_convolute<T>::return_t
209 print_cast(const T& v) { return detail::print_convolute<T>::op(v); }
210 
211 struct escape;
212 
213 epicsShareFunc
214 std::ostream& operator<<(std::ostream& strm, const escape& Q);
215 
218 struct epicsShareClass escape
219 {
220  enum style_t {
221  C, // default
222  CSV, // a la RFC4180
223  };
224 private:
225  const std::string& orig;
226  style_t S;
227 public:
228  escape(const std::string& orig) :orig(orig), S(C) {}
229  ~escape();
231  inline escape& style(style_t s) { S = s; return *this; }
233  std::string str() const;
234 
235  friend
236  epicsShareFunc
237  std::ostream& operator<<(std::ostream& strm, const escape& Q);
238 };
239 
240 struct maybeQuote {
241  const std::string& s;
242  maybeQuote(const std::string& s) :s(s) {}
243 };
244 
245 epicsShareExtern
247 
248 }} // end namespace
249 
250 #endif // PVTYPECAST_H
basic_ostream< _CharT, _Traits > & operator<<(basic_ostream< _CharT, _Traits > &__os, const basic_string< _CharT, _Traits, _Alloc > &__str)
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const std::bernoulli_distribution &__x)
__string_type str() const
uint8_t uint8
Definition: pvType.h:91
basic_string< char > string
Enabler to ensure that both conditions A and B are true.
Definition: templateMeta.h:115
constexpr iterator_traits< _InputIterator >::difference_type count(_InputIterator __first, _InputIterator __last, const _Tp &__value)
detail::pick_type< int8_t, signed char, detail::pick_type< uint8_t, char, unsigned char >::type >::type boolean
Definition: pvType.h:71
escape & style(style_t s)
Change escaping style.
Definition: typeCast.h:231
const _CharT * c_str() const noexcept
int8_t int8
Definition: pvType.h:75