parameter.hh
Go to the documentation of this file.
1 /* -*- mia-c++ -*-
2  *
3  * This file is part of MIA - a toolbox for medical image analysis
4  * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef mia_core_parameters_hh
22 #define mia_core_parameters_hh
23 
24 #include <string>
25 #include <map>
26 #include <ostream>
27 #include <sstream>
28 #include <mia/core/dictmap.hh>
29 #include <mia/core/msgstream.hh>
30 #include <mia/core/handlerbase.hh>
32 
33 
34 namespace xmlpp {
35  class Element;
36 }
37 
39 
49 public:
56  CParameter(const char type[], bool required, const char *descr);
57 
61  virtual ~CParameter();
62 
66  const char *type() const;
70  void descr(std::ostream& os) const;
71 
72 
77  std::string get_value_as_string() const;
78 
83  void value(std::ostream& os) const;
84 
88  bool required_set() const;
89 
93  bool set(const std::string& str_value);
94 
96  const char *get_descr() const;
97 
101  void reset();
102 
108  void add_dependend_handler(HandlerHelpMap& handler_map) const;
109 
111  std::string get_default_value() const;
112 
117  void get_help_xml(xmlpp::Element& root) const;
118 
119 
125  virtual void post_set();
126 
127 protected:
128 
133  virtual void do_descr(std::ostream& os) const = 0;
134 
136  const std::string errmsg(const std::string& err_value) const;
137 private:
141  virtual void do_add_dependend_handler(HandlerHelpMap& handler_map) const;
142  virtual bool do_set(const std::string& str_value) = 0;
143  virtual void do_reset() = 0;
144  virtual std::string do_get_default_value() const = 0;
145  virtual std::string do_get_value_as_string() const = 0;
146  virtual void do_get_help_xml(xmlpp::Element& self) const;
147  bool m_required;
148  bool m_is_required;
149  const char *m_type;
150  const char *m_descr;
151 };
152 
153 
162 template <typename T>
164 
165 public:
171  CTParameter(T& value, bool required, const char *descr);
172 
173 protected:
177  virtual void do_descr(std::ostream& os) const;
178 private:
179  virtual bool do_set(const std::string& str_value);
180  virtual void do_reset();
181  virtual void adjust(T& value);
182  virtual std::string do_get_default_value() const;
183  virtual std::string do_get_value_as_string() const;
184  T& m_value;
185  const T m_default_value;
186 };
187 
196 template <typename T>
198 
199 public:
207  TRangeParameter(T& value, T min, T max, bool required, const char *descr);
208 protected:
212  void do_descr(std::ostream& os) const;
213 private:
214  virtual void adjust(T& value);
215  virtual void do_get_help_xml(xmlpp::Element& self) const;
216  T m_min;
217  T m_max;
218 
219 };
220 
221 
230 template <typename T>
231 class CDictParameter : public CParameter{
232 
233 public:
240  CDictParameter(T& value, const TDictMap<T> dict, const char *descr, bool required = false);
241 protected:
245  virtual void do_descr(std::ostream& os) const;
246 private:
247  virtual bool do_set(const std::string& str_value);
248  virtual void do_reset();
249  virtual std::string do_get_default_value() const;
250  virtual std::string do_get_value_as_string() const;
251  virtual void do_get_help_xml(xmlpp::Element& self) const;
252  T& m_value;
253  T m_default_value;
254  const TDictMap<T> m_dict;
255 
256 };
257 
258 
267 template <typename F>
269 
270 public:
282  TFactoryParameter(typename F::ProductPtr& value, const std::string& init, bool required, const char *descr);
283 
295  TFactoryParameter(typename F::UniqueProduct& value, const std::string& init, bool required, const char *descr);
296 private:
297  virtual void do_descr(std::ostream& os) const;
298  virtual void do_add_dependend_handler(HandlerHelpMap& handler_map)const;
299  virtual bool do_set(const std::string& str_value);
300  virtual void do_reset();
301  virtual std::string do_get_default_value() const;
302  virtual std::string do_get_value_as_string() const;
303  virtual void do_get_help_xml(xmlpp::Element& self) const;
304 
305  typename F::ProductPtr dummy_shared_value;
306  typename F::UniqueProduct dummy_unique_value;
307 
308  typename F::ProductPtr& m_shared_value;
309  typename F::UniqueProduct& m_unique_value;
310 
311  virtual void post_set();
312 
313  std::string m_string_value;
314  std::string m_default_value;
315  bool m_unique;
316 
317 
318 };
319 
320 
321 
332 template <typename T>
333 class CSetParameter : public CParameter{
334 
335 public:
342  CSetParameter(T& value, const std::set<T>& valid_set, const char *descr, bool required = false);
343 protected:
347  virtual void do_descr(std::ostream& os) const;
348 private:
349  virtual bool do_set(const std::string& str_value);
350  virtual void do_reset();
351  virtual std::string do_get_default_value() const;
352  virtual std::string do_get_value_as_string() const;
353  void do_get_help_xml(xmlpp::Element& self) const;
354  T& m_value;
355  T m_default_value;
356  const std::set<T> m_valid_set;
357 
358 };
359 
369 template <typename T>
370 class TParameter : public CParameter{
371 
372 public:
378  TParameter(T& value, bool required, const char *descr);
379 protected:
383  virtual void do_descr(std::ostream& os) const;
384 private:
385  virtual void do_reset();
386  virtual bool do_set(const std::string& str_value);
387  virtual std::string do_get_default_value() const;
388  virtual std::string do_get_value_as_string() const;
389 
390  T& m_value;
391  T m_default_value;
392 };
393 
394 
397 public:
398  CStringParameter(std::string& value, bool required, const char *descr,
399  const CPluginHandlerBase *plugin_hint = NULL);
400 
401 private:
402  virtual void do_reset();
403  virtual bool do_set(const std::string& str_value);
404  virtual std::string do_get_default_value() const;
405  virtual std::string do_get_value_as_string() const;
406 
407  virtual void do_descr(std::ostream& os) const;
408  virtual void do_get_help_xml(xmlpp::Element& self) const;
409  virtual void do_add_dependend_handler(HandlerHelpMap& handler_map)const;
410 
411 
412  std::string& m_value;
413  std::string m_default_value;
414  const CPluginHandlerBase *m_plugin_hint;
415 };
416 
417 
428 
444 template <typename T>
445 CParameter *make_param(std::shared_ptr<T>& value, const std::string& init, bool required, const char *descr)
446 {
447  typedef typename FactoryTrait<T>::type F;
448  return new TFactoryParameter<F>(value, init, required, descr);
449 
450 }
451 
466 template <typename T>
467 CParameter *make_param(std::unique_ptr<T>& value, const std::string& init, bool required, const char *descr)
468 {
469  typedef typename FactoryTrait<T>::type F;
470  return new TFactoryParameter<F>(value, init, required, descr);
471 
472 }
473 
474 
475 template <typename T>
476 CParameter *make_param(T& value, bool required, const char *descr)
477 {
478  return new TParameter<T>(value, required, descr);
479 }
480 
481 
482 
484 
488 template <typename T>
489 struct __dispatch_param_translate {
490  static std::string apply(T x) {
491  std::ostringstream s;
492  s << x;
493  return s.str();
494  }
495 };
496 
497 template <>
498 struct __dispatch_param_translate<std::string> {
499  static std::string apply(const std::string& x) {
500  return x;
501  }
502 };
503 
504 template <>
505 struct __dispatch_param_translate<const char *> {
506  static std::string apply(const char * x) {
507  return std::string(x);
508  }
509 };
510 
512 
513 template <typename T>
514 CDictParameter<T>::CDictParameter(T& value, const TDictMap<T> dict, const char *descr, bool required):
515  CParameter("dict", required, descr),
516  m_value(value),
517  m_default_value(value),
518  m_dict(dict)
519 {
520 }
521 
522 template <typename T>
523 void CDictParameter<T>::do_descr(std::ostream& os) const
524 {
525  for (auto i = m_dict.get_help_begin(); i != m_dict.get_help_end(); ++i) {
526  os << "\n " << i->second.first << ": " << i->second.second;
527  }
528 }
529 
530 template <typename T>
531 void CDictParameter<T>::do_get_help_xml(xmlpp::Element& self) const
532 {
534  auto dict = self.add_child("dict");
535  for (auto i = m_dict.get_help_begin(); i != m_dict.get_help_end(); ++i) {
536  auto v = dict->add_child("value");
537  v->set_attribute("name", i->second.first);
538  v->set_child_text(i->second.second);
539  }
540 }
541 
542 template <typename T>
543 bool CDictParameter<T>::do_set(const std::string& str_value)
544 {
545  m_value = m_dict.get_value(str_value.c_str());
546  return true;
547 }
548 
549 template <typename T>
551 {
552  m_value = m_default_value;
553 }
554 
555 template <typename T>
556 std::string CDictParameter<T>::do_get_default_value() const
557 {
558  return m_dict.get_name(m_default_value);
559 }
560 
561 template <typename T>
563 {
564  return m_dict.get_name(m_value);
565 }
566 
567 template <typename F>
568 TFactoryParameter<F>::TFactoryParameter(typename F::ProductPtr& value,
569  const std::string& init, bool required, const char *descr):
570  CParameter("factory", required, descr),
571  m_shared_value(value),
572  m_unique_value(dummy_unique_value),
573  m_string_value(init),
574  m_default_value(init),
575  m_unique(false)
576 {
577 }
578 
579 template <typename F>
580 TFactoryParameter<F>::TFactoryParameter(typename F::UniqueProduct& value, const std::string& init, bool required, const char *descr):
581  CParameter("factory", required, descr),
582  m_shared_value(dummy_shared_value),
583  m_unique_value(value),
584  m_string_value(init),
585  m_default_value(init),
586  m_unique(true)
587 {
588 }
589 
590 
591 
592 template <typename T>
593 void TFactoryParameter<T>::do_descr(std::ostream& os) const
594 {
595  os << "For a list of available plug-ins see run 'mia-plugin-help "
596  << T::instance().get_descriptor() << "'";
597 }
598 
599 template <typename T>
600 void TFactoryParameter<T>::do_get_help_xml(xmlpp::Element& self) const
601 {
602  auto dict = self.add_child("factory");
603  dict->set_attribute("name", T::instance().get_descriptor());
604 }
605 
606 template <typename T>
607 bool TFactoryParameter<T>::do_set(const std::string& str_value)
608 {
609  m_string_value = str_value;
610  return true;
611 }
612 
613 template <typename T>
615 {
616  if (!m_string_value.empty()) {
617  if (m_unique)
618  m_unique_value = T::instance().produce_unique(m_string_value);
619  else
620  m_shared_value = T::instance().produce(m_string_value);
621  }
622 }
623 
624 template <typename T>
626 {
627  m_string_value = m_default_value;
628 }
629 
630 template <typename T>
632 {
633  // add recursively all dependent handlers
634  if (handler_map.find(T::instance().get_descriptor()) == handler_map.end()){
635  handler_map[T::instance().get_descriptor()] = &T::instance();
636  for (auto i = T::instance().begin(); i != T::instance().end(); ++i)
637  i->second->add_dependend_handlers(handler_map);
638  }
639 }
640 
641 template <typename T>
643 {
644  return m_default_value;
645 }
646 
647 template <typename T>
649 {
650  if (m_unique && m_unique_value)
651  return m_unique_value->get_init_string();
652  if (!m_unique && m_shared_value)
653  return m_shared_value->get_init_string();
654  return m_string_value;
655 }
656 
657 template <typename T>
658 CSetParameter<T>::CSetParameter(T& value, const std::set<T>& valid_set, const char *descr, bool required):
659  CParameter("set", required, descr),
660  m_value(value),
661  m_default_value(value),
662  m_valid_set(valid_set)
663 {
664  if (m_valid_set.empty())
665  throw std::invalid_argument("CSetParameter initialized with empty set");
666 }
667 
668 
669 template <typename T>
670 std::string CSetParameter<T>::do_get_default_value() const
671 {
672  return __dispatch_param_translate<T>::apply(m_default_value);
673 }
674 
675 template <typename T>
677 {
678  return __dispatch_param_translate<T>::apply(m_value);
679 }
680 
681 template <typename T>
682 void CSetParameter<T>::do_descr(std::ostream& os) const
683 {
684  auto i = m_valid_set.begin();
685  auto e = m_valid_set.end();
686 
687  assert ( i != e );
688 
689  os << " Supported values are (" << *i;
690  ++i;
691 
692  while (i != e)
693  os << '|' << *i++;
694  os << ')';
695 }
696 
697 template <typename T>
698 void CSetParameter<T>::do_get_help_xml(xmlpp::Element& self) const
699 {
700  auto set = self.add_child("set");
701  for (auto i = m_valid_set.begin(); i != m_valid_set.end(); ++i) {
702  auto v = set->add_child("value");
703  v->set_attribute("name", __dispatch_param_translate<T>::apply(*i));
704  }
705 }
706 
707 template <typename T>
709 {
710  m_value = m_default_value;
711 }
712 
713 template <typename T>
714 bool CSetParameter<T>::do_set(const std::string& str_value)
715 {
716  std::stringstream s(str_value);
717  T val;
718  s >> val;
719  if (s.fail() || m_valid_set.find(val) == m_valid_set.end()) {
720  throw std::invalid_argument(errmsg(str_value));
721  }
722  m_value = val;
723  return true;
724 }
725 
726 
727 
728 template <typename T>
729 TParameter<T>::TParameter(T& value, bool required, const char *descr):
730  CParameter("streamable", required, descr),
731  m_value(value),
732  m_default_value(value)
733 {
734 }
735 
736 
737 
738 template <typename T>
739 void TParameter<T>::do_descr(std::ostream& os) const
740 {
741  os << m_value;
742 }
743 
744 template <typename T>
745 bool TParameter<T>::do_set(const std::string& str_value)
746 {
747  std::stringstream s(str_value);
748  s >> m_value;
749  if (s.fail())
750  throw std::invalid_argument(errmsg(str_value));
751  return true;
752 }
753 
754 template <typename T>
756 {
757  m_value = m_default_value;
758 }
759 
760 template <typename T>
761 std::string TParameter<T>::do_get_default_value() const
762 {
763  std::ostringstream s;
764  s << m_default_value;
765  auto str = s.str();
766  if (str.find(',') != std::string::npos) {
767  std::ostringstream s2;
768  s2 << '[' << str << ']';
769  str = s2.str();
770  }
771  return str;
772 }
773 
774 template <typename T>
775 std::string TParameter<T>::do_get_value_as_string() const
776 {
777  return __dispatch_param_translate<T>::apply(m_value);
778 }
779 
781 
782 #endif