attributes.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_attributes_hh
22 #define mia_core_attributes_hh
23 
24 #include <mia/core/msgstream.hh>
25 #include <mia/core/errormacro.hh>
26 #include <map>
27 #include <memory>
28 #include <string>
29 #include <cstring>
30 #include <vector>
31 #include <iostream>
32 #include <sstream>
33 #include <stdexcept>
34 #include <boost/any.hpp>
35 #include <boost/ref.hpp>
36 #include <mia/core/defines.hh>
37 
39 
49 public:
51  virtual ~CAttribute();
52 
54  std::string as_string() const;
55 
60  bool is_equal(const CAttribute& other) const;
61 
68  bool is_less(const CAttribute& other) const;
69 
71  virtual const char *typedescr() const = 0;
72 private:
73  virtual std::string do_as_string() const = 0;
74 
75  virtual bool do_is_equal(const CAttribute& other) const = 0;
76 
77  virtual bool do_is_less(const CAttribute& other) const = 0;
78 };
79 
80 
81 inline
82 std::ostream& operator << (std::ostream& os, const CAttribute& attr) {
83  os << attr.as_string();
84  return os;
85 };
86 
87 inline bool operator == (const CAttribute& a, const CAttribute& b)
88 {
89  return a.is_equal(b);
90 }
91 
92 inline bool operator < (const CAttribute& a, const CAttribute& b)
93 {
94  return a.is_less(b);
95 }
96 
98 typedef std::shared_ptr<CAttribute > PAttribute;
99 
100 struct pattr_less {
101  bool operator () (PAttribute const& a, PAttribute const& b)
102  {
103  return *a < *b;
104  }
105 };
106 
120 template <typename T>
122 public:
124 
125 
129  TAttribute(typename ::boost::reference_wrapper<T>::type value);
131 
132 
137  operator T()const;
138 
140  virtual const char *typedescr() const;
141 protected:
143  const T& get_value() const;
144 private:
145  virtual std::string do_as_string() const;
146  virtual bool do_is_equal(const CAttribute& other) const;
147  virtual bool do_is_less(const CAttribute& other) const;
148 
149  T m_value;
150 };
151 
161 template <typename T>
163  const TAttribute<T>& a = dynamic_cast<const TAttribute<T>&>(attr);
164  return a;
165 }
166 
172 
178 
184 
190 
196 
202 
203 
209 
215 
220 typedef std::map<std::string, PAttribute> CAttributeMap;
221 
227 
232 typedef std::shared_ptr<CAttributeMap > PAttributeMap;
233 
234 
242 EXPORT_CORE std::ostream& operator << (std::ostream& os, const CAttributeMap& data);
243 
244 
253 public:
254 
256 
257 
258  CAttributedData();
259  CAttributedData(const CAttributedData& org);
260 
266 
268 
270  CAttributedData& operator =(const CAttributedData& org);
271 
276  const PAttribute get_attribute(const std::string& key) const;
277 
281  CAttributeMap::const_iterator begin_attributes() const;
282 
286  CAttributeMap::const_iterator end_attributes() const;
287 
294  void set_attribute(const std::string& key, PAttribute attr);
295 
296 
302  void set_attributes(CAttributeMap::const_iterator begin, CAttributeMap::const_iterator end);
303 
309  void set_attribute(const std::string& key, const std::string& value);
310 
312  const std::string get_attribute_as_string(const std::string& key)const;
313 
314 
322  template <typename T>
323  const T get_attribute_as(const std::string& key)const;
324 
330  void delete_attribute(const std::string& key);
331 
337  bool has_attribute(const std::string& key)const;
338 
340  friend EXPORT_CORE bool operator == (const CAttributedData& a, const CAttributedData& b);
342 private:
343  PAttributeMap m_attr;
344 };
345 
346 
347 
356 EXPORT_CORE bool operator == (const CAttributeMap& am, const CAttributeMap& bm);
357 
358 
367 public:
369  virtual ~CAttrTranslator() {};
370 
375  PAttribute from_string(const std::string& value) const;
376 private:
377  virtual PAttribute do_from_string(const std::string& value) const = 0;
378 protected:
379  CAttrTranslator();
380 
385  void do_register(const std::string& key);
386 };
387 
397 public:
405  PAttribute to_attr(const std::string& key, const std::string& value) const;
406 
408  static CStringAttrTranslatorMap& instance();
409 private:
410  friend class CAttrTranslator;
419  void add(const std::string& key, const CAttrTranslator * const t);
420 
421  typedef std::map<std::string, const CAttrTranslator * const> CMap;
422  CMap m_translators;
423 };
424 
425 
437 template <typename T>
438 void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, T value)
439 {
440  cvdebug() << "add attribute " << key << " of type " << typeid(T).name() << " and value '" << value << "'\n";
441  attributes[key] = PAttribute(new TAttribute<T>(value));
442 }
443 
452 template <>
453 void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, const char * value);
454 
455 
466 template <typename T>
468 public:
475  static void register_for(const std::string& key);
476 private:
477  virtual PAttribute do_from_string(const std::string& value) const;
478 };
479 
480 
481 // template implementation
482 
483 template <typename T>
484 TAttribute<T>::TAttribute(typename ::boost::reference_wrapper<T>::type value):
485  m_value(value)
486 {
487 }
488 
489 template <typename T>
491 {
492  return m_value;
493 }
494 
495 template <typename T>
496 const T& TAttribute<T>::get_value() const
497 {
498  return m_value;
499 }
500 
501 template <typename T>
502 const char *TAttribute<T>::typedescr() const
503 {
504  return typeid(T).name();
505 }
506 
514 template <typename T>
515 struct dispatch_attr_string {
516  static std::string val2string(const typename ::boost::reference_wrapper<T>::type value) {
517  std::stringstream sval;
518  sval << value;
519  return sval.str();
520  }
521  static T string2val(const std::string& str) {
522  T v;
523  std::istringstream svalue(str);
524  svalue >> v;
525  return v;
526  }
527 };
528 
529 
530 template <typename T>
531 struct dispatch_attr_string<std::vector<T> > {
532  static std::string val2string(const std::vector<T>& value) {
533  std::stringstream sval;
534  sval << value.size();
535  for (size_t i = 0; i < value.size(); ++i)
536  sval << " " << value[i];
537  return sval.str();
538  }
539  static std::vector<T> string2val(const std::string& str) {
540  size_t s;
541  std::istringstream svalue(str);
542  std::vector<T> v;
543  svalue >> s;
544  if (s > v.max_size())
545  throw create_exception<std::runtime_error>("string2val: try to create a vector of size ",
546  s, " but support only size ", v.max_size());
547  v.resize(s);
548  for (size_t i = 0; i < s; ++i)
549  svalue >> v[i];
550  if (svalue.fail()) {
551  std::stringstream msg;
552  msg << "string2val: unable to convert '" << str << "'";
553  throw std::invalid_argument(msg.str());
554  }
555  return v;
556  }
557 };
558 
559 
560 template <>
561 struct dispatch_attr_string<std::vector<bool> > {
562  static std::string val2string(const std::vector<bool>& value) {
563  std::stringstream sval;
564  sval << value.size();
565  for (size_t i = 0; i < value.size(); ++i)
566  sval << " " << value[i];
567  return sval.str();
568  }
569  static std::vector<bool> string2val(const std::string& str) {
570  size_t s;
571  std::istringstream svalue(str);
572  svalue >> s;
573  std::vector<bool> v(s);
574  for (size_t i = 0; i < s; ++i) {
575  bool value;
576  svalue >> value;
577  v[i] = value;
578  }
579  if (svalue.fail()) {
580  std::stringstream msg;
581  msg << "string2val: unable to convert '" << str << "'";
582  throw std::invalid_argument(msg.str());
583  }
584  return v;
585  }
586 };
587 
588 template <>
589 struct dispatch_attr_string<unsigned char> {
590  static std::string val2string(unsigned char value) {
591  std::stringstream sval;
592  sval << (unsigned int)value;
593  return sval.str();
594  }
595  static unsigned char string2val(const std::string& str) {
596  unsigned int v;
597  std::istringstream svalue(str);
598  svalue >> v;
599  return (unsigned char)v;
600  }
601 };
602 
603 template <>
604 struct dispatch_attr_string<signed char> {
605  static std::string val2string(signed char value) {
606  std::stringstream sval;
607  sval << (signed int)value;
608  return sval.str();
609  }
610  static signed char string2val(const std::string& str) {
611  int v;
612  std::istringstream svalue(str);
613  svalue >> v;
614  return (signed char)v;
615  }
616 };
617 
618 template <>
619 struct dispatch_attr_string<std::string> {
620  static std::string val2string(std::string value) {
621  return value;
622  }
623  static std::string string2val(const std::string& str) {
624  return str;
625  }
626 };
627 
628 template <>
629 struct dispatch_attr_string<CAttributeMap> {
630  static std::string val2string(const CAttributeMap& /*value*/) {
631  throw std::invalid_argument("Conversion of a CAttributeMap to a string not implemented");
632  }
633  static CAttributeMap string2val(const std::string& /*str*/) {
634  throw std::invalid_argument("Conversion of a string to a CAttributeMap not implemented");
635  }
636 };
637 
639 
640 template <typename T>
641 std::string TAttribute<T>::do_as_string() const
642 {
643  return dispatch_attr_string<T>::val2string(m_value);
644 }
645 
646 template <typename T>
647 bool TAttribute<T>::do_is_equal(const CAttribute& other) const
648 {
649  const TAttribute<T>* o = dynamic_cast<const TAttribute<T> *>(&other);
650  if (!o) {
651  cvdebug() << "TAttribute<T>::do_is_equal:Cast to "
652  << typeid(const TAttribute<T>*).name()
653  << "failed\n";
654  return false;
655  }
656  return m_value == o->m_value;
657 }
658 
659 template <typename T>
660 bool TAttribute<T>::do_is_less(const CAttribute& other) const
661 {
662  const TAttribute<T>* o = dynamic_cast<const TAttribute<T> *>(&other);
663  if (o)
664  return m_value < o->m_value;
665 
666  return strcmp(typedescr(), other.typedescr()) < 0;
667 }
668 
669 #if 0
670 template <typename T>
671 TVAttribute<T>::TVAttribute(const std::vector<T>& value):
672  TAttribute<std::vector<T> >(value)
673 {
674 }
675 
676 template <typename T>
677 bool TVAttribute<T>::do_is_equal(const CAttribute& other) const
678 {
679  const TVAttribute<T>* o = dynamic_cast<const TVAttribute<T> *>(&other);
680  if (!o)
681  return false;
682  return o->get_value().size() == this->get_value().size() &&
683  std::equal(this->get_value().begin(), this->get_value().end(), o->get_value().begin());
684 };
685 #endif
686 
687 template <typename T>
688 void TTranslator<T>::register_for(const std::string& key)
689 {
690  static TTranslator<T> me;
691  me.do_register(key);
692 }
693 
694 template <typename T>
695 PAttribute TTranslator<T>::do_from_string(const std::string& value) const
696 {
697  return PAttribute(new TAttribute<T>(dispatch_attr_string<T>::string2val(value)));
698 }
699 
700 template <typename T>
701 const T CAttributedData::get_attribute_as(const std::string& key)const
702 {
703  PAttribute attr = get_attribute(key);
704  if (attr)
705  return dynamic_cast<const TAttribute<T>&>(*attr);
706  else
707  throw create_exception<std::invalid_argument>("CAttributedData: no attribute '", key, "' found");
708 }
709 
710 
711 
714 
717 
718 #ifdef LONG_64BIT
721 
724 #endif
725 
728 
731 
734 
737 
740 
743 
746 
748 
749 #endif