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-2016 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Pub
8 lic License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program 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 MIA; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef mia_core_parameters_hh
23 #define mia_core_parameters_hh
24 
25 #include <string>
26 #include <map>
27 #include <ostream>
28 #include <istream>
29 #include <sstream>
30 #include <memory>
31 #include <mia/core/flags.hh>
32 #include <mia/core/dictmap.hh>
33 #include <mia/core/msgstream.hh>
34 #include <mia/core/handlerbase.hh>
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(CXMLElement& 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(CXMLElement& 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 
208 enum class EParameterBounds : int {
209  bf_min = 1,
210  bf_min_open = 3,
211  bf_min_closed = 5,
212  bf_min_flags = 7,
213  bf_max = 0x10,
214  bf_max_open = 0x30,
215  bf_max_closed = 0x50,
216  bf_max_flags = 0x70,
217  bf_closed_interval = 0x55,
218  bf_open_interval = 0x33
219  };
220 
222 
223 
224 EXPORT_CORE std::ostream& operator << (std::ostream& os, EParameterBounds flags);
225 
226 template <typename T>
228 
229 public:
230 
241  TBoundedParameter(T& value, EParameterBounds flags, const std::vector<T>& boundaries, bool required, const char *descr);
242 protected:
246  void do_descr(std::ostream& os) const;
247 private:
248  virtual void adjust(T& value);
249  virtual void do_get_help_xml(CXMLElement& self) const;
250  T m_min;
251  T m_max;
252  EParameterBounds m_flags;
253 };
254 
255 template <typename T>
256 CParameter *make_param(T& value, bool required, const char *descr)
257 {
258  return new CTParameter<T>(value, required, descr);
259 }
260 
261 
262 template <typename T, typename S>
263 CParameter *make_lo_param(T& value, S lower_bound, bool required, const char *descr)
264 {
266  {static_cast<T>(lower_bound)}, required, descr);
267 }
268 
269 template <typename T>
270 CParameter *make_positive_param(T& value, bool required, const char *descr)
271 {
272  return new TBoundedParameter<T>(value, EParameterBounds::bf_min_open, {T()}, required, descr);
273 }
274 
275 template <typename T, typename S>
276 CParameter *make_lc_param(T& value, S lower_bound, bool required, const char *descr)
277 {
279  {static_cast<T>(lower_bound)}, required, descr);
280 }
281 
282 
283 template <typename T>
284 CParameter *make_nonnegative_param(T& value, bool required, const char *descr)
285 {
286  return new TBoundedParameter<T>(value, EParameterBounds::bf_min_closed, {T()}, required, descr);
287 }
288 
289 
290 template <typename T, typename S>
291 CParameter *make_uo_param(T& value, S upper_bound, bool required, const char *descr)
292 {
294  {static_cast<T>(upper_bound)}, required, descr);
295 }
296 
297 template <typename T, typename S>
298 CParameter *make_uc_param(T& value, S upper_bound, bool required, const char *descr)
299 {
301  {static_cast<T>(upper_bound)}, required, descr);
302 }
303 
304 template <typename T, typename S1, typename S2>
305 CParameter *make_ci_param(T& value, S1 lower_bound, S2 upper_bound, bool required, const char *descr)
306 {
308  {static_cast<T>(lower_bound), static_cast<T>(upper_bound)}, required, descr);
309 }
310 
311 template <typename T, typename S1, typename S2>
312 CParameter *make_oi_param(T& value, S1 lower_bound, S2 upper_bound, bool required, const char *descr)
313 {
315  {static_cast<T>(lower_bound), static_cast<T>(upper_bound)}, required, descr);
316 }
317 
318 template <typename T, typename S1, typename S2>
319 CParameter *make_coi_param(T& value, S1 lower_bound, S2 upper_bound,bool required, const char *descr)
320 {
322  {static_cast<T>(lower_bound), static_cast<T>(upper_bound)}, required, descr);
323 }
324 
325 template <typename T, typename S1, typename S2>
326 CParameter *make_oci_param(T& value, S1 lower_bound, S2 upper_bound,bool required, const char *descr)
327 {
329  {static_cast<T>(lower_bound), static_cast<T>(upper_bound)}, required, descr);
330 }
331 
332 
333 
342 template <typename T>
343 class CDictParameter : public CParameter{
344 
345 public:
352  CDictParameter(T& value, const TDictMap<T>& dict, const char *descr, bool required = false);
353 protected:
357  virtual void do_descr(std::ostream& os) const;
358 private:
359  virtual bool do_set(const std::string& str_value);
360  virtual void do_reset();
361  virtual std::string do_get_default_value() const;
362  virtual std::string do_get_value_as_string() const;
363  virtual void do_get_help_xml(CXMLElement& self) const;
364  T& m_value;
365  T m_default_value;
366  const TDictMap<T> m_dict;
367 
368 };
369 
370 
379 template <typename F>
381 
382 public:
394  TFactoryParameter(typename F::ProductPtr& value, const std::string& init, bool required, const char *descr);
395 
407  TFactoryParameter(typename F::UniqueProduct& value, const std::string& init, bool required, const char *descr);
408 private:
409  virtual void do_descr(std::ostream& os) const;
410  virtual void do_add_dependend_handler(HandlerHelpMap& handler_map)const;
411  virtual bool do_set(const std::string& str_value);
412  virtual void do_reset();
413  virtual std::string do_get_default_value() const;
414  virtual std::string do_get_value_as_string() const;
415  virtual void do_get_help_xml(CXMLElement& self) const;
416 
417  typename F::ProductPtr dummy_shared_value;
418  typename F::UniqueProduct dummy_unique_value;
419 
420  typename F::ProductPtr& m_shared_value;
421  typename F::UniqueProduct& m_unique_value;
422 
423  virtual void post_set();
424 
425  std::string m_string_value;
426  std::string m_default_value;
427  bool m_unique;
428 
429 
430 };
431 
432 
433 
444 template <typename T>
445 class CSetParameter : public CParameter{
446 
447 public:
454  CSetParameter(T& value, const std::set<T>& valid_set, const char *descr, bool required = false);
455 protected:
459  virtual void do_descr(std::ostream& os) const;
460 private:
461  virtual bool do_set(const std::string& str_value);
462  virtual void do_reset();
463  virtual std::string do_get_default_value() const;
464  virtual std::string do_get_value_as_string() const;
465  void do_get_help_xml(CXMLElement& self) const;
466  T& m_value;
467  T m_default_value;
468  const std::set<T> m_valid_set;
469 
470 };
471 
481 template <typename T>
482 class TParameter : public CParameter{
483 
484 public:
490  TParameter(T& value, bool required, const char *descr);
491 protected:
495  virtual void do_descr(std::ostream& os) const;
496 private:
497  virtual void do_reset();
498  virtual bool do_set(const std::string& str_value);
499  virtual std::string do_get_default_value() const;
500  virtual std::string do_get_value_as_string() const;
501 
502  T& m_value;
503  T m_default_value;
504 };
505 
506 
509 public:
510  CStringParameter(std::string& value, CCmdOptionFlags flags, const char *descr,
511  const CPluginHandlerBase *plugin_hint = nullptr);
512 
513 private:
514  virtual void do_reset();
515  virtual bool do_set(const std::string& str_value);
516  virtual std::string do_get_default_value() const;
517  virtual std::string do_get_value_as_string() const;
518 
519  virtual void do_descr(std::ostream& os) const;
520  virtual void do_get_help_xml(CXMLElement& self) const;
521  virtual void do_add_dependend_handler(HandlerHelpMap& handler_map)const;
522 
523 
524  std::string& m_value;
525  std::string m_default_value;
526  CCmdOptionFlags m_flags;
527  const CPluginHandlerBase *m_plugin_hint;
528 };
529 
530 
533 
534 
541 
548 
553 
569 template <typename T>
570 CParameter *make_param(std::shared_ptr<T>& value, const std::string& init, bool required, const char *descr)
571 {
572  typedef typename FactoryTrait<T>::type F;
573  return new TFactoryParameter<F>(value, init, required, descr);
574 
575 }
576 
591 template <typename T>
592 CParameter *make_param(std::unique_ptr<T>& value, const std::string& init, bool required, const char *descr)
593 {
594  typedef typename FactoryTrait<T>::type F;
595  return new TFactoryParameter<F>(value, init, required, descr);
596 
597 }
598 
599 
600 
601 
603 
607 template <typename T>
608 struct __dispatch_param_translate {
609  static std::string apply(T x) {
610  std::ostringstream s;
611  s << x;
612  return s.str();
613  }
614 };
615 
616 template <>
617 struct __dispatch_param_translate<std::string> {
618  static std::string apply(const std::string& x) {
619  return x;
620  }
621 };
622 
623 template <>
624 struct __dispatch_param_translate<const char *> {
625  static std::string apply(const char * x) {
626  return std::string(x);
627  }
628 };
629 
631 
632 template <typename T>
633 CDictParameter<T>::CDictParameter(T& value, const TDictMap<T>& dict, const char *descr, bool required):
634  CParameter("dict", required, descr),
635  m_value(value),
636  m_default_value(value),
637  m_dict(dict)
638 {
639 }
640 
641 template <typename T>
642 void CDictParameter<T>::do_descr(std::ostream& os) const
643 {
644  for (auto i = m_dict.get_help_begin(); i != m_dict.get_help_end(); ++i) {
645  os << "\n " << i->second.first << ": " << i->second.second;
646  }
647 }
648 
649 template <typename T>
651 {
653  auto dict = self.add_child("dict");
654  for (auto i = m_dict.get_help_begin(); i != m_dict.get_help_end(); ++i) {
655  auto v = dict->add_child("value");
656  v->set_attribute("name", i->second.first);
657  v->set_child_text(i->second.second);
658  }
659 }
660 
661 template <typename T>
662 bool CDictParameter<T>::do_set(const std::string& str_value)
663 {
664  m_value = m_dict.get_value(str_value.c_str());
665  return true;
666 }
667 
668 template <typename T>
670 {
671  m_value = m_default_value;
672 }
673 
674 template <typename T>
675 std::string CDictParameter<T>::do_get_default_value() const
676 {
677  return m_dict.get_name(m_default_value);
678 }
679 
680 template <typename T>
682 {
683  return m_dict.get_name(m_value);
684 }
685 
686 template <typename F>
688  const std::string& init, bool required, const char *descr):
689  CParameter("factory", required, descr),
690  m_shared_value(value),
691  m_unique_value(dummy_unique_value),
692  m_string_value(init),
693  m_default_value(init),
694  m_unique(false)
695 {
696 }
697 
698 template <typename F>
699 TFactoryParameter<F>::TFactoryParameter(typename F::UniqueProduct& value, const std::string& init, bool required, const char *descr):
700  CParameter("factory", required, descr),
701  m_shared_value(dummy_shared_value),
702  m_unique_value(value),
703  m_string_value(init),
704  m_default_value(init),
705  m_unique(true)
706 {
707 }
708 
709 
710 
711 template <typename T>
712 void TFactoryParameter<T>::do_descr(std::ostream& os) const
713 {
714  os << "For a list of available plug-ins see run 'mia-plugin-help "
715  << T::instance().get_descriptor() << "'";
716 }
717 
718 template <typename T>
720 {
721  auto dict = self.add_child("factory");
722  dict->set_attribute("name", T::instance().get_descriptor());
723 }
724 
725 template <typename T>
726 bool TFactoryParameter<T>::do_set(const std::string& str_value)
727 {
728  m_string_value = str_value;
729  return true;
730 }
731 
732 template <typename T>
734 {
735  if (!m_string_value.empty()) {
736  if (m_unique)
737  m_unique_value = T::instance().produce_unique(m_string_value);
738  else
739  m_shared_value = T::instance().produce(m_string_value);
740  }
741 }
742 
743 template <typename T>
745 {
746  m_string_value = m_default_value;
747 }
748 
749 template <typename T>
751 {
752  // add recursively all dependent handlers
753  if (handler_map.find(T::instance().get_descriptor()) == handler_map.end()){
754  handler_map[T::instance().get_descriptor()] = &T::instance();
755  for (auto i = T::instance().begin(); i != T::instance().end(); ++i)
756  i->second->add_dependend_handlers(handler_map);
757  }
758 }
759 
760 template <typename T>
762 {
763  return m_default_value;
764 }
765 
766 template <typename T>
768 {
769  if (m_unique && m_unique_value)
770  return m_unique_value->get_init_string();
771  if (!m_unique && m_shared_value)
772  return m_shared_value->get_init_string();
773  return m_string_value;
774 }
775 
776 template <typename T>
777 CSetParameter<T>::CSetParameter(T& value, const std::set<T>& valid_set, const char *descr, bool required):
778  CParameter("set", required, descr),
779  m_value(value),
780  m_default_value(value),
781  m_valid_set(valid_set)
782 {
783  if (m_valid_set.empty())
784  throw std::invalid_argument("CSetParameter initialized with empty set");
785 }
786 
787 
788 template <typename T>
789 std::string CSetParameter<T>::do_get_default_value() const
790 {
791  return __dispatch_param_translate<T>::apply(m_default_value);
792 }
793 
794 template <typename T>
796 {
797  return __dispatch_param_translate<T>::apply(m_value);
798 }
799 
800 template <typename T>
801 void CSetParameter<T>::do_descr(std::ostream& os) const
802 {
803  auto i = m_valid_set.begin();
804  auto e = m_valid_set.end();
805 
806  assert ( i != e );
807 
808  os << " Supported values are (" << *i;
809  ++i;
810 
811  while (i != e)
812  os << '|' << *i++;
813  os << ')';
814 }
815 
816 template <typename T>
818 {
819  auto set = self.add_child("set");
820  for (auto i = m_valid_set.begin(); i != m_valid_set.end(); ++i) {
821  auto v = set->add_child("value");
822  v->set_attribute("name", __dispatch_param_translate<T>::apply(*i));
823  }
824 }
825 
826 template <typename T>
828 {
829  m_value = m_default_value;
830 }
831 
832 template <typename T>
833 bool CSetParameter<T>::do_set(const std::string& str_value)
834 {
835  std::stringstream s(str_value);
836  T val;
837  s >> val;
838  if (s.fail() || m_valid_set.find(val) == m_valid_set.end()) {
839  throw std::invalid_argument(errmsg(str_value));
840  }
841  m_value = val;
842  return true;
843 }
844 
845 
846 
847 template <typename T>
849  CParameter("streamable", required, descr),
850  m_value(value),
851  m_default_value(value)
852 {
853 }
854 
855 
856 
857 template <typename T>
858 void TParameter<T>::do_descr(std::ostream& os) const
859 {
860  os << m_value;
861 }
862 
863 template <typename T>
864 bool TParameter<T>::do_set(const std::string& str_value)
865 {
866  std::stringstream s(str_value);
867  s >> m_value;
868  if (s.fail())
869  throw std::invalid_argument(errmsg(str_value));
870  return true;
871 }
872 
873 template <typename T>
875 {
876  m_value = m_default_value;
877 }
878 
879 template <typename T>
880 std::string TParameter<T>::do_get_default_value() const
881 {
882  std::ostringstream s;
883  s << m_default_value;
884  auto str = s.str();
885  if (str.find(',') != std::string::npos) {
886  std::ostringstream s2;
887  s2 << '[' << str << ']';
888  str = s2.str();
889  }
890  return str;
891 }
892 
893 template <typename T>
894 std::string TParameter<T>::do_get_value_as_string() const
895 {
896  return __dispatch_param_translate<T>::apply(m_value);
897 }
898 
899 
901 
902 #endif
void descr(std::ostream &os) const
CSetParameter(T &value, const std::set< T > &valid_set, const char *descr, bool required=false)
Definition: parameter.hh:777
CParameter * make_oci_param(T &value, S1 lower_bound, S2 upper_bound, bool required, const char *descr)
Definition: parameter.hh:326
CParameter * make_positive_param(T &value, bool required, const char *descr)
Definition: parameter.hh:270
CParameter * make_param(T &value, bool required, const char *descr)
Definition: parameter.hh:256
TBoundedParameter< int > CSIBoundedParameter
an signed int parameter (with possible boundaries)
Definition: parameter.hh:545
TBoundedParameter< double > CDBoundedParameter
an float parameter, double accuracy (with possible boundaries)
Definition: parameter.hh:552
TBoundedParameter< unsigned short > CUSBoundedParameter
an unsigned short parameter (with possible boundaries)
Definition: parameter.hh:536
virtual void do_descr(std::ostream &os) const
Definition: parameter.hh:858
A parameter that get&#39;s initialized by a factory to a shared or unique pointer.
Definition: parameter.hh:380
TBoundedParameter< long > CSLBoundedParameter
an signed long parameter (with possible boundaries)
Definition: parameter.hh:547
const std::string errmsg(const std::string &err_value) const
create an error message by using the given value that raises the error
CParameter * make_oi_param(T &value, S1 lower_bound, S2 upper_bound, bool required, const char *descr)
Definition: parameter.hh:312
CParameter * make_lc_param(T &value, S lower_bound, bool required, const char *descr)
Definition: parameter.hh:276
void value(std::ostream &os) const
A parameter that can only assume values out of a limited set.
Definition: parameter.hh:445
CTParameter< bool > CBoolParameter
boolean parameter
Definition: parameter.hh:532
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
TFactoryParameter(typename F::ProductPtr &value, const std::string &init, bool required, const char *descr)
Definition: parameter.hh:687
The base class for parameters used in complex options.
Definition: parameter.hh:48
std::map< std::string, const CPluginHandlerBase * > HandlerHelpMap
A map that is used to collect the plug-in handlers used in a program.
Definition: handlerbase.hh:36
The base class for all plugin handlers.
Definition: handlerbase.hh:57
Generic type of a complex paramter.
Definition: parameter.hh:163
CParameter * make_uo_param(T &value, S upper_bound, bool required, const char *descr)
Definition: parameter.hh:291
EParameterBounds
Scalar parameter with an expected value range.
Definition: parameter.hh:208
virtual void do_descr(std::ostream &os) const =0
A parameter that can assume any value of the given value type.
Definition: parameter.hh:482
TBoundedParameter< float > CFBoundedParameter
an float parameter, single accuracy (with possible boundaries)
Definition: parameter.hh:550
virtual void do_descr(std::ostream &os) const
Definition: parameter.hh:642
#define TRACE_FUNCTION
Definition: msgstream.hh:202
CCmdOptionFlags
CParameter * make_uc_param(T &value, S upper_bound, bool required, const char *descr)
Definition: parameter.hh:298
This class implements a facade for the xml Element.
Definition: xmlinterface.hh:42
CParameter * make_coi_param(T &value, S1 lower_bound, S2 upper_bound, bool required, const char *descr)
Definition: parameter.hh:319
CParameter * make_nonnegative_param(T &value, bool required, const char *descr)
Definition: parameter.hh:284
TBoundedParameter< short > CSSBoundedParameter
an signed short parameter (with possible boundaries)
Definition: parameter.hh:543
CParameter * make_ci_param(T &value, S1 lower_bound, S2 upper_bound, bool required, const char *descr)
Definition: parameter.hh:305
#define EXPORT_CORE
Macro to manage Visual C++ style dllimport/dllexport.
Definition: defines.hh:101
TBoundedParameter< unsigned int > CUIBoundedParameter
an unsigned int parameter (with possible boundaries)
Definition: parameter.hh:538
an string parameter
Definition: parameter.hh:508
CParameter * make_lo_param(T &value, S lower_bound, bool required, const char *descr)
Definition: parameter.hh:263
IMPLEMENT_FLAG_OPERATIONS(EParameterBounds)
virtual void do_descr(std::ostream &os) const
Definition: parameter.hh:801
Dictionary parameter.
Definition: parameter.hh:343
TBoundedParameter< unsigned long > CULBoundedParameter
an unsigned long parameter (with possible boundaries)
Definition: parameter.hh:540
EXPORT_CORE std::ostream & operator<<(std::ostream &os, EParameterBounds flags)
TParameter(T &value, bool required, const char *descr)
Definition: parameter.hh:848
CDictParameter(T &value, const TDictMap< T > &dict, const char *descr, bool required=false)
Definition: parameter.hh:633
A mapper from emums to string values. - usefull for names flags.
Definition: dictmap.hh:45
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36