NSVD Reader  0.0.1
value_setter.hpp
Go to the documentation of this file.
1 
5 /*
6  * These codes are licensed under CC0.
7  * http://creativecommons.org/publicdomain/zero/1.0/
8  */
9 #ifndef __NODAMUSHI_SVD_VALUE_VALUE_SETTER_HPP__
10 #define __NODAMUSHI_SVD_VALUE_VALUE_SETTER_HPP__
11 
12 # include <type_traits>
13 # include <limits>
14 # include <vector>
15 
18 # include "nodamushi/box.hpp"
19 # include "nodamushi/boxvec.hpp"
20 # include "nodamushi/svd/node.hpp"
21 # include "nodamushi/svd/create.hpp"
22 
23 namespace nodamushi{
24 namespace svd{
25 
26 template<typename DST,typename SRC>struct value_setter;
27 template<typename DST,typename SRC>
28 bool apply_value_setter(DST& dst,const SRC& src)
29 {
30  return value_setter<DST,SRC>::set(dst,src);
31 }
32 
33 //-------------------------------------------------------------------------
34 // value try set
35 //-------------------------------------------------------------------------
36 template<typename DST,typename SVD>
37 auto _value_try_set(DST& dst,SVD& src)
38  ->typename std::enable_if<std::is_base_of<svd_node,DST>::value, bool>::type
39 {
40  return create(src, dst);
41 }
42 
43 template<typename DST,typename SVD>
44 auto _value_try_set(DST& dst,SVD& src)
45  ->typename std::enable_if<!std::is_base_of<svd_node,DST>::value, bool>::type
46 {
47  return apply_value_setter(dst,src.get_value());
48 }
49 
50 template<typename DST,typename SVD>
51 bool value_try_set(DST& dst,SVD& src)
52 {
53  return _value_try_set(dst,src);
54 }
55 
56 template<typename DST,typename SVD>
57 bool value_try_set(std::vector<DST>& dst,SVD& src)
58 {
59  size_t s = dst.size();
60  dst.emplace_back();
61  if(!value_try_set(dst[s],src)){
62  dst.pop_back();
63  return false;
64  }
65  return true;
66 }
67 
68 template<typename DST,typename SVD>
69 bool value_try_set(std::vector<nodamushi::box<DST>>& dst,SVD& src)
70 {
71  box<DST> tmp{new DST{}};
72  DST& d = *tmp;
73  if(value_try_set(d,src)){
74  dst.emplace_back(std::move(tmp));
75  return true;
76  }
77  return false;
78 }
79 
80 
81 template<typename DST,typename PTR,typename SVD>
83 {
84  box<DST> tmp{new DST{}};
85  DST& d = *tmp;
86  if(value_try_set(d,src)){
87  dst.push_back(std::move(tmp));
88  return true;
89  }
90  return false;
91 }
92 
93 template<typename DST,typename SVD>
95 {
96  box<DST> tmp{new DST{}};
97  DST& d = *tmp;
98  if(value_try_set(d,src)){
99  dst = std::move(tmp);
100  return true;
101  }
102  return false;
103 }
104 //-------------------------------------------------------------------------
105 
106 namespace details{
107 
108 template<typename I,bool UNSIG>struct irange;
109 template<typename I>struct irange<I,true>
110 {
111  using limits = std::numeric_limits<I>;
112  static constexpr I MAX = limits::max();
113  static bool in_range(unsigned long long v){return v <= MAX;}
114 };
115 template<typename I>struct irange<I,false>
116 {
117  using limits = std::numeric_limits<I>;
118  static constexpr I MAX = limits::max();
119  static constexpr I MIN = limits::min();
120  static bool in_range(long long v){return MIN <= v && v <= MAX;}
121 };
122 
123 template<typename I>
124 bool cast_integer(const char* const ptr,size_t length,I& dst)
125 {
126  constexpr bool unsig = std::is_unsigned<I>::value;
127  using ir = irange<I,unsig>;
128  using LL = std::conditional_t<unsig, unsigned long long, long long>;
129  char *str_end=nullptr;
130  LL v = static_cast<LL>(std::strtoll(
131  ptr,&str_end,
132  (length > 2 && *ptr == '0' &&
133  (ptr[1] == 'x' || ptr[1] == 'X'))? 16:10));
134  size_t use = str_end - ptr;
135  if(!ir::in_range(v) || use != length){
136  return false;
137  }
138  dst = static_cast<I>(v);
139  return true;
140 }
141 
142 template<typename I> bool cast_integer(const std::string& src,I& dst)
143 {
144  return cast_integer(src.c_str(),src.length(),dst);
145 }
146 
147 # if __cplusplus >= 201703
148 template<typename I> bool cast_integer(const std::string_view& s,I& dst)
149 {
150  std::string src(s);
151  return cast_integer(src.c_str() ,src.length(),dst);
152 }
153 # endif
154 
155 
156 template<typename DST>
157 auto value_setter_set(DST& dst,const std::string& src)
158  -> typename std::enable_if<
159  std::is_integral<DST>::value&&!enum_helper<DST>::HAS_HELPER
160  &&!std::is_same<DST,bool>::value
161  ,bool>::type
162 {
163  bool b = details::cast_integer(src,dst);
164  // TODO throw number format error ?
165  return b;
166 }
167 
168 template<typename DST>
169 auto value_setter_set(DST& dst,const std::string& src)
170  -> typename std::enable_if<enum_helper<DST>::HAS_HELPER ,bool>::type
171 {
172  bool b =enum_helper<DST>::get(src,dst);
173  // TODO throw number format error ?
174  return b;
175 }
176 
177 
178 template<typename DST>
179 auto value_setter_set(DST& dst,const std::string& src)
180  -> typename std::enable_if<value_setter_helper<DST>::value ,bool>::type
181 {
182  bool b =value_setter_helper<DST>::set(src,dst);
183  return b;
184 }
185 
186 
187 template<typename DST>
188 bool value_setter_set(bool& dst,const std::string& src)
189 {
190  if(src == "true" || src == "1"){
191  dst = true;
192  return true;
193  }else if(src == "false" || src == "0"){
194  dst = false;
195  return true;
196  }
197  return false;
198 }
199 
200 # if __cplusplus >= 201703
201 
202 
203 template<typename DST>
204 auto value_setter_set(DST& dst,std::string_view s)
205  -> typename std::enable_if<
206  std::is_integral<DST>::value&&!enum_helper<DST>::HAS_HELPER
207  &&!std::is_same<DST,bool>::value
208  ,bool>::type
209 {
210  std::string src(s);
211  bool b = details::cast_integer(src,dst);
212  // TODO throw number format error ?
213  return b;
214 }
215 
216 template<typename DST>
217 auto value_setter_set(DST& dst,std::string_view s)
218  -> typename std::enable_if<enum_helper<DST>::HAS_HELPER ,bool>::type
219 {
220  std::string src(s);
221  bool b =enum_helper<DST>::get(src,dst);
222  // TODO throw number format error ?
223  return b;
224 }
225 
226 template<typename DST>
227 auto value_setter_set(DST& dst,std::string_view src)
228  -> typename std::enable_if<value_setter_helper<DST>::value ,bool>::type
229 {
230  bool b =value_setter_helper<DST>::set(src,dst);
231  return b;
232 }
233 
234 template<typename DST>
235 bool value_setter_set(bool& dst,std::string_view src)
236 {
237 
238  if(src == "true"){
239  dst = true;
240  return true;
241  }else if(src == "false"){
242  dst = false;
243  return true;
244  }
245  return false;
246 }
247 
248 # endif
249 
250 
251 } // end namespace details
252 
253 
254 
255 
256 template<typename T>struct value_setter<T,T>
257 {
258  static bool set(T& dst,const T& src){
259  dst = src;
260  return true;
261  }
262  static bool move(T& dst,T&& src){dst =std::move(src);return true;}
263 };
264 
265 template<typename DST>struct value_setter<DST,std::string>
266 {
267  static bool set(DST& dst,const std::string& src)
268  {
269  return details::value_setter_set<DST>(dst,src);
270  }
271 
272  static auto move(DST& dst, std::string&& src)
273  {
274  return details::value_setter_set<DST>(dst,src);
275  }
276 };
277 
278 template<>struct value_setter<std::string,std::string>
279 {
280  static bool set(std::string& dst, const std::string& src)
281  {
282  dst = src; return true;
283  }
284 
285  static bool move(std::string& dst,std::string&& src)
286  {
287  dst = std::move(src); return true;
288  }
289 };
290 
291 
292 //-----------------------------------------------------------------------------
293 # if __cplusplus >= 201703
294 
295 template<typename DST>struct value_setter<DST,std::string_view>
296 {
297  static bool set(DST& dst,const std::string_view& src)
298  {
299  return details::value_setter_set<DST>(dst,src);
300  }
301 
302  static auto move(DST& dst, std::string_view&& src)
303  {
304  return details::value_setter_set<DST>(dst,src);
305  }
306 };
307 
308 template<>struct value_setter<std::string_view,std::string_view>
309 {
310  static bool set(std::string_view& dst, const std::string_view& src)
311  {
312  dst = src; return true;
313  }
314  static bool move(std::string_view& dst, std::string_view&& src)
315  {
316  dst = src; return true;
317  }
318 };
319 template<>struct value_setter<std::string,std::string_view>
320 {
321  static bool set(std::string& dst, const std::string_view& src)
322  {
323  dst = std::string(src); return true;
324  }
325  static bool move(std::string& dst,std::string_view&& src)
326  {
327  dst = std::string(src); return true;
328  }
329 };
330 
331 # endif
332 
333 
334 }} // end namespace nodamushi::svd
335 
336 
337 #endif // __NODAMUSHI_SVD_VALUE_VALUE_SETTER_HPP__
boxvec. vector<pointer<X>>
provide getter,setter
Definition: enum_helper.hpp:18
static bool move(std::string &dst, std::string &&src)
auto _value_try_set(DST &dst, SVD &src) -> typename std::enable_if< std::is_base_of< svd_node, DST >::value, bool >::type
Definition: Access.hpp:143
box.std::unique_ptr wrapper
static bool in_range(unsigned long long v)
bool cast_integer(const char *const ptr, size_t length, I &dst)
static auto move(DST &dst, std::string &&src)
static bool set(T &dst, const T &src)
bool create(SVD &svd, AddressBlock &d)
build AddressBlock
bool apply_value_setter(DST &dst, const SRC &src)
void push_back(const T &t)
Definition: boxvec.hpp:168
create fucntion decralation
bool value_try_set(DST &dst, SVD &src)
static bool set(std::string &dst, const std::string &src)
svd element marker interface
vector<pointer<T>>.
Definition: boxvec.hpp:75
static bool set(DST &dst, const std::string &src)
auto value_setter_set(DST &dst, const std::string &src) -> typename std::enable_if< std::is_integral< DST >::value &&!enum_helper< DST >::HAS_HELPER &&!std::is_same< DST, bool >::value, bool >::type
static bool move(T &dst, T &&src)