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  svalue >> s;
543  std::vector<T> v(s);
544  for (size_t i = 0; i < s; ++i)
545  svalue >> v[i];
546  if (svalue.fail()) {
547  std::stringstream msg;
548  msg << "string2val: unable to convert '" << str << "'";
549  throw std::invalid_argument(msg.str());
550  }
551  return v;
552  }
553 };
554 
555 
556 template <>
557 struct dispatch_attr_string<std::vector<bool> > {
558  static std::string val2string(const std::vector<bool>& value) {
559  std::stringstream sval;
560  sval << value.size();
561  for (size_t i = 0; i < value.size(); ++i)
562  sval << " " << value[i];
563  return sval.str();
564  }
565  static std::vector<bool> string2val(const std::string& str) {
566  size_t s;
567  std::istringstream svalue(str);
568  svalue >> s;
569  std::vector<bool> v(s);
570  for (size_t i = 0; i < s; ++i) {
571  bool value;
572  svalue >> value;
573  v[i] = value;
574  }
575  if (svalue.fail()) {
576  std::stringstream msg;
577  msg << "string2val: unable to convert '" << str << "'";
578  throw std::invalid_argument(msg.str());
579  }
580  return v;
581  }
582 };
583 
584 template <>
585 struct dispatch_attr_string<unsigned char> {
586  static std::string val2string(unsigned char value) {
587  std::stringstream sval;
588  sval << (unsigned int)value;
589  return sval.str();
590  }
591  static unsigned char string2val(const std::string& str) {
592  unsigned int v;
593  std::istringstream svalue(str);
594  svalue >> v;
595  return (unsigned char)v;
596  }
597 };
598 
599 template <>
600 struct dispatch_attr_string<signed char> {
601  static std::string val2string(signed char value) {
602  std::stringstream sval;
603  sval << (signed int)value;
604  return sval.str();
605  }
606  static signed char string2val(const std::string& str) {
607  int v;
608  std::istringstream svalue(str);
609  svalue >> v;
610  return (signed char)v;
611  }
612 };
613 
614 template <>
615 struct dispatch_attr_string<std::string> {
616  static std::string val2string(std::string value) {
617  return value;
618  }
619  static std::string string2val(const std::string& str) {
620  return str;
621  }
622 };
623 
624 template <>
625 struct dispatch_attr_string<CAttributeMap> {
626  static std::string val2string(const CAttributeMap& /*value*/) {
627  throw std::invalid_argument("Conversion of a CAttributeMap to a string not implemented");
628  // avoid warnings ...
629  return std::string("");
630  }
631  static CAttributeMap string2val(const std::string& /*str*/) {
632  throw std::invalid_argument("Conversion of a string to a CAttributeMap not implemented");
633  // avoid warnings ...
634  return CAttributeMap();
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