GNU Radio 3.7.0 C++ API
rpcregisterhelpers.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2012 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef RPCREGISTERHELPERS_H
24 #define RPCREGISTERHELPERS_H
25 
26 #include <stdio.h>
27 #include <sstream>
28 #include <iostream>
30 #include <gnuradio/rpcmanager.h>
34 
35 // Base classes
36 template<typename T, typename Tto> class rpcextractor_base
37  : public virtual gr::messages::msg_accepter
38 {
39 public:
40  rpcextractor_base(T* source, void (T::*func)(Tto)) :
41  _source(source), _func(func) {;}
43 
44  void post(pmt::pmt_t which_port, pmt::pmt_t msg) {
45  throw std::runtime_error("rpcextractor_base: no post defined for this data type.\n");
46  }
47 
48 protected:
49  T* _source;
50  void (T::*_func)(Tto);
51 };
52 
53 template<typename T, typename Tto>
54 class rpcbasic_extractor : public virtual rpcextractor_base<T,Tto>
55 {
56 public:
57  rpcbasic_extractor(T* source, void (T::*func)(Tto)) :
58  rpcextractor_base<T,Tto>(source, func)
59  {;}
60 };
61 
62 template<typename T, typename Tfrom>
64 {
65 public:
66  rpcinserter_base(T* source, Tfrom (T::*func)()) : _source(source), _func(func) {;}
68 
69  pmt::pmt_t retrieve() { assert(0); return pmt::pmt_t(); }
70 
71 protected:
72  T* _source;
73  Tfrom (T::*_func)();
74 };
75 
76 template<typename T, typename Tfrom>
78  public virtual rpcinserter_base<T,Tfrom>
79 {
80 public:
81  rpcbasic_inserter(T* source, Tfrom (T::*func)()const)
82  : rpcinserter_base<T,Tfrom>(source, func)
83  {;}
84 
85  rpcbasic_inserter(T* source, Tfrom (T::*func)())
86  : rpcinserter_base<T,Tfrom>(source, func)
87  {;}
88 
90  {
93  }
94 };
95 
96 // Specialized Extractor Templates
97 template<typename T>
98 class rpcbasic_extractor<T,double> : public virtual rpcextractor_base<T,double>
99 {
100 public:
101  rpcbasic_extractor(T* source, void (T::*func)(double))
102  : rpcextractor_base<T,double>(source, func)
103  {;}
104 
105  void post(pmt::pmt_t which_port, pmt::pmt_t msg)
106  {
108  (pmt::to_double(msg));
109  }
110 };
111 
112 template<typename T>
113 class rpcbasic_extractor<T,float> : public virtual rpcextractor_base<T,float>
114 {
115 public:
116  rpcbasic_extractor(T* source, void (T::*func)(float))
117  : rpcextractor_base<T,float>(source, func)
118  {;}
119 
120  void post(pmt::pmt_t which_port, pmt::pmt_t msg)
121  {
123  (pmt::to_double(msg));
124  }
125 };
126 
127 template<typename T>
128 class rpcbasic_extractor<T,long> : public virtual rpcextractor_base<T,long>
129 {
130 public:
131  rpcbasic_extractor(T* source, void (T::*func)(long))
132  : rpcextractor_base<T,long>(source, func)
133  {;}
134 
135  void post(pmt::pmt_t which_port, pmt::pmt_t msg)
136  {
138  (pmt::to_long(msg));
139  }
140 };
141 
142 template<typename T>
143 class rpcbasic_extractor<T,int> : public virtual rpcextractor_base<T,int>
144 {
145 public:
146  rpcbasic_extractor(T* source, void (T::*func)(int))
147  : rpcextractor_base<T,int>(source, func)
148  {;}
149 
150  void post(pmt::pmt_t which_port, pmt::pmt_t msg)
151  {
153  (pmt::to_long(msg));
154  }
155 };
156 
157 template<typename T>
158 class rpcbasic_extractor<T,bool> : public virtual rpcextractor_base<T,bool>
159 {
160 public:
161  rpcbasic_extractor(T* source, void (T::*func)(bool))
162  : rpcextractor_base<T,bool>(source, func)
163  {;}
164 
165  void post(pmt::pmt_t which_port, pmt::pmt_t msg)
166  {
168  (pmt::to_bool(msg));
169  }
170 };
171 
172 template<typename T>
173 class rpcbasic_extractor<T,std::complex<float> >
174  : public virtual rpcextractor_base<T,std::complex<float> >
175 {
176 public:
177  rpcbasic_extractor(T* source, void (T::*func)(std::complex<float>))
178  : rpcextractor_base<T,std::complex<float> >(source, func)
179  {;}
180 
181  void post(pmt::pmt_t which_port, pmt::pmt_t msg)
182  {
183  std::complex<float> k = static_cast<std::complex<float> >(pmt::to_complex(msg));
186  }
187 };
188 
189 template<typename T>
190 class rpcbasic_extractor<T,std::complex<double> >
191  : public virtual rpcextractor_base<T,std::complex<double> >
192 {
193 public:
194  rpcbasic_extractor(T* source, void (T::*func)(std::complex<double>))
195  : rpcextractor_base<T,std::complex<double> >(source, func)
196  {;}
197 
198  void post(pmt::pmt_t which_port, pmt::pmt_t msg)
199  {
202  }
203 };
204 
205 template<typename T>
206 class rpcbasic_extractor<T,std::string>
207  : public virtual rpcextractor_base<T,std::string>
208 {
209 public:
210  rpcbasic_extractor(T* source, void (T::*func)(std::string))
211  : rpcextractor_base<T,std::string>(source, func)
212  {;}
213 
214  void post(pmt::pmt_t which_port, pmt::pmt_t msg)
215  {
218  }
219 };
220 
221 template<typename T>
222 class rpcbasic_inserter<T,uint64_t> : public virtual rpcinserter_base<T,uint64_t>
223 {
224 public:
225  rpcbasic_inserter(T* source, uint64_t (T::*func)() const)
226  : rpcinserter_base<T,uint64_t>(source, func)
227  {;}
228 
229  rpcbasic_inserter(T* source, uint64_t (T::*func)())
230  : rpcinserter_base<T,uint64_t>(source, func)
231  {;}
232 
234  {
237  }
238 };
239 
240 template<typename T>
241 class rpcbasic_inserter<T,std::vector< int > >
242  : public virtual rpcinserter_base<T,std::vector< int > >
243 {
244 public:
245  rpcbasic_inserter(T* source, std::vector<int > (T::*func)() const)
246  : rpcinserter_base<T,std::vector<int > >(source, func)
247  {;}
248 
249  rpcbasic_inserter(T* source, std::vector<int > (T::*func)())
250  : rpcinserter_base<T,std::vector<int > >(source, func)
251  {;}
252 
254  {
255  std::vector< int >
256  vec((rpcinserter_base<T,std::vector<int > >::
257  _source->*rpcinserter_base<T,std::vector< int > >::_func)());
258  return pmt::init_s32vector(vec.size(), &vec[0]);
259  }
260 };
261 
262 template<typename T>
263 class rpcbasic_inserter<T,std::vector< std::complex<float> > >
264  : public virtual rpcinserter_base<T,std::vector< std::complex<float> > >
265 {
266 public:
267  rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)() const)
268  : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func)
269  {;}
270 
271  rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)())
272  : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func)
273  {;}
274 
276  {
277  std::vector< std::complex<float> >
278  vec((rpcinserter_base<T,std::vector<std::complex<float> > >::
279  _source->*rpcinserter_base<T,std::vector< std::complex<float> > >::_func)());
280  return pmt::init_c32vector(vec.size(), &vec[0]);
281  }
282 };
283 
284 template<typename T>
285 class rpcbasic_inserter<T,std::vector< float> >
286  : public virtual rpcinserter_base<T,std::vector< float > >
287 {
288 public:
289  rpcbasic_inserter(T* source, std::vector<float> (T::*func)() const)
290  : rpcinserter_base<T,std::vector<float > >(source, func)
291  {;}
292 
293  rpcbasic_inserter(T* source, std::vector<float> (T::*func)())
294  : rpcinserter_base<T,std::vector<float> >(source, func)
295  {;}
296 
298  {
299  std::vector< float > vec((rpcinserter_base<T,std::vector<float> >::
300  _source->*rpcinserter_base<T,std::vector< float> >::_func)());
301  return pmt::init_f32vector(vec.size(), &vec[0]);
302  }
303 };
304 
305 template<typename T>
306 class rpcbasic_inserter<T,std::vector< uint8_t> >
307  : public virtual rpcinserter_base<T,std::vector< uint8_t > > {
308 public:
309  rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)() const)
310  : rpcinserter_base<T,std::vector<uint8_t > >(source, func)
311  {;}
312 
313  rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)())
314  : rpcinserter_base<T,std::vector<uint8_t> >(source, func)
315  {;}
316 
318  {
319  std::vector< uint8_t > vec((rpcinserter_base<T,std::vector<uint8_t> >::
320  _source->*rpcinserter_base<T,std::vector< uint8_t> >::_func)());
321  return pmt::init_u8vector(vec.size(), &vec[0]);
322  }
323 };
324 
325 template<typename T>
326 class rpcbasic_inserter<T,std::complex<float> >
327  : public virtual rpcinserter_base<T,std::complex<float > > {
328 public:
329  rpcbasic_inserter(T* source, std::complex<float> (T::*func)() const)
330  : rpcinserter_base<T,std::complex<float> >(source, func)
331  {;}
332 
333  rpcbasic_inserter(T* source, std::complex<float> (T::*func)())
334  : rpcinserter_base<T,std::complex<float> >(source, func)
335  {;}
336 
338  {
339  std::complex<float > k((rpcinserter_base<T,std::complex<float> >::
340  _source->*rpcinserter_base<T,std::complex<float> >::_func)());
341  return pmt::from_complex(k);
342  }
343 };
344 
345 template<typename T>
346 class rpcbasic_inserter<T,std::complex<double> >
347  : public virtual rpcinserter_base<T,std::complex<double > > {
348 public:
349  rpcbasic_inserter(T* source, std::complex<double> (T::*func)() const)
350  : rpcinserter_base<T,std::complex<double> >(source, func)
351  {;}
352 
353  rpcbasic_inserter(T* source, std::complex<double> (T::*func)())
354  : rpcinserter_base<T,std::complex<double> >(source, func)
355  {;}
356 
358  {
359  std::complex<double > k((rpcinserter_base<T,std::complex<double> >::
360  _source->*rpcinserter_base<T,std::complex<double> >::_func)());
361  return pmt::from_complex(k);
362  }
363 };
364 
365 template <typename T>
367 {
369 protected: static int count;
370 };
371 
372 // Base class to inherit from and create universal shared pointers.
374 {
375 public:
377  virtual ~rpcbasic_base() {};
378 };
379 
381 
382 template<typename T, typename Tto>
384 {
385  // Function used to add a 'set' RPC call using a basic_block's alias.
386  rpcbasic_register_set(const std::string& block_alias,
387  const char* functionbase,
388  void (T::*function)(Tto),
389  const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
390  const char* units_ = "",
391  const char* desc_ = "",
392  priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
393  DisplayType display_ = DISPNULL)
394  {
395  d_min = min;
396  d_max = max;
397  d_def = def;
398  d_units = units_;
399  d_desc = desc_;
400  d_minpriv = minpriv_;
401  d_display = display_;
402  d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
403 #ifdef RPCSERVER_ENABLED
405  extractor(new rpcbasic_extractor<T,Tto>(d_object, function),
406  minpriv_, std::string(units_),
407  display_, std::string(desc_), min, max, def);
408  std::ostringstream oss(std::ostringstream::out);
409  oss << block_alias << "::" << functionbase;
410  d_id = oss.str();
411  //std::cerr << "REGISTERING SET: " << d_id << " " << desc_ << std::endl;
412  rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor);
413 #endif
414  }
415 
416  // Function used to add a 'set' RPC call using a name and the object
417  rpcbasic_register_set(const std::string& name,
418  const char* functionbase,
419  T* obj,
420  void (T::*function)(Tto),
421  const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
422  const char* units_ = "",
423  const char* desc_ = "",
424  priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
425  DisplayType display_ = DISPNULL)
426  {
427  d_min = min;
428  d_max = max;
429  d_def = def;
430  d_units = units_;
431  d_desc = desc_;
432  d_minpriv = minpriv_;
433  d_display = display_;
434  d_object = obj;
435 #ifdef RPCSERVER_ENABLED
437  extractor(new rpcbasic_extractor<T,Tto>(d_object, function),
438  minpriv_, std::string(units_),
439  display_, std::string(desc_), min, max, def);
440  std::ostringstream oss(std::ostringstream::out);
441  oss << name << "::" << functionbase;
442  d_id = oss.str();
443  //std::cerr << "REGISTERING SET: " << d_id << " " << desc_ << std::endl;
444  rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor);
445 #endif
446  }
447 
449  {
450 #ifdef RPCSERVER_ENABLED
452 #endif
453  }
454 
455 
456  pmt::pmt_t min() const { return d_min; }
457  pmt::pmt_t max() const { return d_max; }
458  pmt::pmt_t def() const { return d_def; }
459  std::string units() const { return d_units; }
460  std::string description() const { return d_desc; }
461  priv_lvl_t privilege_level() const { return d_minpriv; }
462  DisplayType default_display() const { return d_display; }
463 
464  void set_min(pmt::pmt_t p) { d_min = p; }
465  void set_max(pmt::pmt_t p) { d_max = p; }
466  void set_def(pmt::pmt_t p) { d_def = p; }
467  void units(std::string u) { d_units = u; }
468  void description(std::string d) { d_desc = d; }
469  void privilege_level(priv_lvl_t p) { d_minpriv = p; }
470  void default_display(DisplayType d) { d_display = d; }
471 
472 private:
473  std::string d_id;
474  pmt::pmt_t d_min, d_max, d_def;
475  std::string d_units, d_desc;
476  priv_lvl_t d_minpriv;
477  DisplayType d_display;
478  T *d_object;
479 };
480 
481 
482 template<typename T, typename Tfrom>
484 {
485 public:
486  // Function used to add a 'set' RPC call using a basic_block's alias.
487  // primary constructor to allow for T get() functions
488  rpcbasic_register_get(const std::string& block_alias,
489  const char* functionbase,
490  Tfrom (T::*function)(),
491  const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
492  const char* units_ = "",
493  const char* desc_ = "",
494  priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
495  DisplayType display_ = DISPNULL)
496  {
497  d_min = min;
498  d_max = max;
499  d_def = def;
500  d_units = units_;
501  d_desc = desc_;
502  d_minpriv = minpriv_;
503  d_display = display_;
504  d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
505 #ifdef RPCSERVER_ENABLED
507  inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function),
508  minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
509  std::ostringstream oss(std::ostringstream::out);
510  oss << block_alias << "::" << functionbase;
511  d_id = oss.str();
512  //std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl;
513  rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
514 #endif
515  }
516 
517 
518  // alternate constructor to allow for T get() const functions
519  rpcbasic_register_get(const std::string& block_alias,
520  const char* functionbase,
521  Tfrom (T::*function)() const,
522  const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
523  const char* units_ = "",
524  const char* desc_ = "",
525  priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
526  DisplayType display_ = DISPNULL)
527  {
528  d_min = min;
529  d_max = max;
530  d_def = def;
531  d_units = units_;
532  d_desc = desc_;
533  d_minpriv = minpriv_;
534  d_display = display_;
535  d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
536 #ifdef RPCSERVER_ENABLED
538  inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function),
539  minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
540  std::ostringstream oss(std::ostringstream::out);
541  oss << block_alias << "::" << functionbase;
542  d_id = oss.str();
543  //std::cerr << "REGISTERING GET CONST: " << d_id << " " << desc_ << " " << display_ << std::endl;
544  rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
545 #endif
546  }
547 
548  // Function used to add a 'set' RPC call using a name and the object
549  // primary constructor to allow for T get() functions
550  rpcbasic_register_get(const std::string& name,
551  const char* functionbase,
552  T* obj,
553  Tfrom (T::*function)(),
554  const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
555  const char* units_ = "",
556  const char* desc_ = "",
557  priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
558  DisplayType display_ = DISPNULL)
559  {
560  d_min = min;
561  d_max = max;
562  d_def = def;
563  d_units = units_;
564  d_desc = desc_;
565  d_minpriv = minpriv_;
566  d_display = display_;
567  d_object = obj;
568 #ifdef RPCSERVER_ENABLED
570  inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function),
571  minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
572  std::ostringstream oss(std::ostringstream::out);
573  oss << name << "::" << functionbase;
574  d_id = oss.str();
575  //std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl;
576  rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
577 #endif
578  }
579 
580 
581  // alternate constructor to allow for T get() const functions
582  rpcbasic_register_get(const std::string& name,
583  const char* functionbase,
584  T* obj,
585  Tfrom (T::*function)() const,
586  const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
587  const char* units_ = "",
588  const char* desc_ = "",
589  priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
590  DisplayType display_ = DISPNULL)
591  {
592  d_min = min;
593  d_max = max;
594  d_def = def;
595  d_units = units_;
596  d_desc = desc_;
597  d_minpriv = minpriv_;
598  d_display = display_;
599  d_object = obj;
600 #ifdef RPCSERVER_ENABLED
602  inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function),
603  minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
604  std::ostringstream oss(std::ostringstream::out);
605  oss << name << "::" << functionbase;
606  d_id = oss.str();
607  //std::cerr << "REGISTERING GET CONST: " << d_id << " " << desc_ << " " << display_ << std::endl;
608  rpcmanager::get()->i()->registerQueryCallback(d_id, inserter);
609 #endif
610  }
611 
613  {
614 #ifdef RPCSERVER_ENABLED
616 #endif
617  }
618 
619  pmt::pmt_t min() const { return d_min; }
620  pmt::pmt_t max() const { return d_max; }
621  pmt::pmt_t def() const { return d_def; }
622  std::string units() const { return d_units; }
623  std::string description() const { return d_desc; }
624  priv_lvl_t privilege_level() const { return d_minpriv; }
625  DisplayType default_display() const { return d_display; }
626 
627  void set_min(pmt::pmt_t p) { d_min = p; }
628  void set_max(pmt::pmt_t p) { d_max = p; }
629  void set_def(pmt::pmt_t p) { d_def = p; }
630  void units(std::string u) { d_units = u; }
631  void description(std::string d) { d_desc = d; }
632  void privilege_level(priv_lvl_t p) { d_minpriv = p; }
633  void default_display(DisplayType d) { d_display = d; }
634 
635 private:
636  std::string d_id;
637  pmt::pmt_t d_min, d_max, d_def;
638  std::string d_units, d_desc;
639  priv_lvl_t d_minpriv;
640  DisplayType d_display;
641  T *d_object;
642 };
643 
644 /*
645  * This class can wrap a pre-existing variable type for you
646  * it will define the getter and rpcregister call for you.
647  *
648  * It should be used for read-only getters.
649  *
650  */
651 template<typename Tfrom>
653 {
654 protected:
656  Tfrom *d_variable;
657  Tfrom get() { return *d_variable; }
658 public:
659  // empty constructor which should never be called but needs to exist for ues in varous STL data structures
660  void setptr(Tfrom* _variable){ rpcbasic_register_variable<Tfrom>::d_variable = _variable; }
662  d_rpc_reg("FAIL", "FAIL", this, &rpcbasic_register_variable::get,
663  pmt::PMT_NIL, pmt::PMT_NIL, pmt::PMT_NIL, DISPNULL,
664  "FAIL", "FAIL", RPC_PRIVLVL_MIN),
665  d_variable(NULL)
666  {
667  throw std::runtime_error("ERROR: rpcbasic_register_variable called with no args. If this happens, someone has tried to use rpcbasic_register_variable incorrectly.");
668  };
669 
670  rpcbasic_register_variable(const std::string& namebase,
671  const char* functionbase,
672  Tfrom *variable,
673  const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
674  const char* units_ = "",
675  const char* desc_ = "",
676  priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
677  DisplayType display_=DISPNULL) :
678  d_rpc_reg(namebase, functionbase, this, &rpcbasic_register_variable::get,
679  min, max, def, units_, desc_, minpriv_, display_),
680  d_variable(variable)
681  {
682  //std::cerr << "REGISTERING VAR: " << " " << desc_ << std::endl;
683  }
684 };
685 
686 template<typename Tfrom> class rpcbasic_register_variable_rw : public rpcbasic_register_variable<Tfrom> {
687  private:
689  public:
690  // empty constructor which should never be called but needs to exist for ues in varous STL data structures
692  d_rpc_regset("FAIL","FAIL",this,&rpcbasic_register_variable<Tfrom>::get,pmt::PMT_NIL,pmt::PMT_NIL,pmt::PMT_NIL,DISPNULL,"FAIL","FAIL",RPC_PRIVLVL_MIN)
693  {
694  throw std::runtime_error("ERROR: rpcbasic_register_variable_rw called with no args. if this happens someone used rpcbasic_register_variable_rw incorrectly.\n");
695  };
696  void set(Tfrom _variable){ *(rpcbasic_register_variable<Tfrom>::d_variable) = _variable; }
698  const std::string& namebase,
699  const char* functionbase,
700  Tfrom *variable,
701  const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
702  const char* units_ = "",
703  const char* desc_ = "",
704  priv_lvl_t minpriv = RPC_PRIVLVL_MIN,
705  DisplayType display_=DISPNULL) :
706  rpcbasic_register_variable<Tfrom>(namebase,functionbase,variable,min,max,def,units_,desc_),
707  d_rpc_regset(namebase,functionbase,this,&rpcbasic_register_variable_rw::set,min,max,def,units_,desc_,minpriv,display_)
708  {
709  // no action
710  }
711 };
712 
713 
714 
715 
716 #endif