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-2015 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 <boost/lexical_cast.hpp>
38 
40 
50 public:
52  virtual ~CAttribute();
53 
55  std::string as_string() const;
56 
61  bool is_equal(const CAttribute& other) const;
62 
69  bool is_less(const CAttribute& other) const;
70 
72  virtual const char *typedescr() const = 0;
73 
75  virtual int type_id() const = 0;
76 private:
77  virtual std::string do_as_string() const = 0;
78 
79  virtual bool do_is_equal(const CAttribute& other) const = 0;
80 
81  virtual bool do_is_less(const CAttribute& other) const = 0;
82 };
83 
84 
85 inline
86 std::ostream& operator << (std::ostream& os, const CAttribute& attr) {
87  os << attr.as_string();
88  return os;
89 };
90 
91 inline bool operator == (const CAttribute& a, const CAttribute& b)
92 {
93  return a.is_equal(b);
94 }
95 
96 
98 typedef std::shared_ptr<CAttribute > PAttribute;
99 
113 template <typename T>
115 public:
117 
118 
122  TAttribute(typename ::boost::reference_wrapper<T>::type value);
124 
125 
130  operator T()const;
131 
133  virtual const char *typedescr() const;
134 
135  virtual int type_id() const;
136 protected:
138  const T& get_value() const;
139 private:
140  virtual std::string do_as_string() const;
141  virtual bool do_is_equal(const CAttribute& other) const;
142  virtual bool do_is_less(const CAttribute& other) const;
143 
144  T m_value;
145 };
146 
156 template <typename T>
158  const TAttribute<T>& a = dynamic_cast<const TAttribute<T>&>(attr);
159  return a;
160 }
161 
167 
173 
179 
185 
191 
197 
198 
204 
210 
215 typedef std::map<std::string, PAttribute> CAttributeMap;
216 
217 template <>
219  static const int value = 1000;
220 };
221 
222 
228 
233 typedef std::shared_ptr<CAttributeMap > PAttributeMap;
234 
235 
243 EXPORT_CORE std::ostream& operator << (std::ostream& os, const CAttributeMap& data);
244 
245 
254 public:
255 
257 
258 
259  CAttributedData();
260  CAttributedData(const CAttributedData& org);
261 
267 
269 
271  CAttributedData& operator =(const CAttributedData& org);
272 
277  const PAttribute get_attribute(const std::string& key) const;
278 
282  CAttributeMap::const_iterator begin_attributes() const;
283 
287  CAttributeMap::const_iterator end_attributes() const;
288 
295  void set_attribute(const std::string& key, PAttribute attr);
296 
297 
303  void set_attributes(CAttributeMap::const_iterator begin, CAttributeMap::const_iterator end);
304 
310  void set_attribute(const std::string& key, const std::string& value);
311 
312 
319  template <typename T>
320  void set_attribute(const std::string& key, const T& value);
321 
327  void set_attribute(const std::string& key, const char* value);
328 
329 
331  const std::string get_attribute_as_string(const std::string& key)const;
332 
333 
341  template <typename T>
342  const T get_attribute_as(const std::string& key)const;
343 
352  template <typename T>
353  const T get_attribute_as(const std::string& key, T default_value)const;
354 
360  void delete_attribute(const std::string& key);
361 
367  bool has_attribute(const std::string& key)const;
368 
370  friend EXPORT_CORE bool operator == (const CAttributedData& a, const CAttributedData& b);
372 
373  void print(std::ostream& os) const {
374  os << *m_attr;
375  }
376 private:
377  PAttributeMap m_attr;
378 };
379 
380 
381 inline std::ostream& operator << (std::ostream& os, const CAttributedData& data)
382 {
383  data.print(os);
384  return os;
385 }
386 
387 
388 
397 EXPORT_CORE bool operator == (const CAttributeMap& am, const CAttributeMap& bm);
398 
399 
408 public:
410  virtual ~CAttrTranslator() {};
411 
416  PAttribute from_string(const std::string& value) const;
417 private:
418  virtual PAttribute do_from_string(const std::string& value) const = 0;
419 protected:
420  CAttrTranslator();
421 
426  bool do_register(const std::string& key);
427 };
428 
438 public:
446  PAttribute to_attr(const std::string& key, const std::string& value) const;
447 
449  static CStringAttrTranslatorMap& instance();
450 private:
451  friend class CAttrTranslator;
460  bool add(const std::string& key, CAttrTranslator * t);
461 
462  typedef std::map<std::string, std::shared_ptr<CAttrTranslator>> CMap;
463  CMap m_translators;
464 };
465 
466 
478 template <typename T>
479 void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, T value)
480 {
481  cvdebug() << "add attribute " << key << " of type " << typeid(T).name() << " and value '" << value << "'\n";
482  attributes[key] = PAttribute(new TAttribute<T>(value));
483 }
484 
485 template <>
486 inline void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, const char *value)
487 {
488  attributes[key] = CStringAttrTranslatorMap::instance().to_attr(key, value);
489  cvdebug() << "add_attribute '" << key
490  << "' to '" << value << "' of type '"
491  << attributes[key]->typedescr() << "'\n";
492 }
493 
494 
495 
506 template <typename T>
508 public:
515  static bool register_for(const std::string& key);
516 private:
517  virtual PAttribute do_from_string(const std::string& value) const;
518 };
519 
520 
521 // template implementation
522 
523 template <typename T>
524 TAttribute<T>::TAttribute(typename ::boost::reference_wrapper<T>::type value):
525  m_value(value)
526 {
527 }
528 
529 template <typename T>
531 {
532  return m_value;
533 }
534 
535 template <typename T>
536 const T& TAttribute<T>::get_value() const
537 {
538  return m_value;
539 }
540 
541 template <typename T>
542 const char *TAttribute<T>::typedescr() const
543 {
544  return typeid(T).name();
545 }
546 
547 template <typename T>
549 {
551  "You must provide a type specialization for attribute_type<T>");
552 
553  return attribute_type<T>::value;
554 }
555 
565 template <typename T>
566 struct dispatch_attr_string {
567  static std::string val2string(const typename ::boost::reference_wrapper<T>::type value) {
568  std::stringstream sval;
569  sval << boost::lexical_cast<std::string>(value);
570  return sval.str();
571  }
572  static T string2val(const std::string& str) {
573  T v;
574  std::istringstream svalue(str);
575  svalue >> v;
576  return v;
577  }
578 };
579 
580 
581 template <typename T>
582 struct dispatch_attr_string<std::vector<T> > {
583  static std::string val2string(const std::vector<T>& value) {
584  std::stringstream sval;
585  sval << value.size();
586  for (size_t i = 0; i < value.size(); ++i)
587  sval << " " << boost::lexical_cast<std::string>(value[i]);
588  return sval.str();
589  }
590  static std::vector<T> string2val(const std::string& str) {
591  size_t s;
592  std::istringstream svalue(str);
593  std::vector<T> v;
594  svalue >> s;
595  if (s > v.max_size())
596  throw create_exception<std::runtime_error>("string2val: try to create a vector of size ",
597  s, " but support only size ", v.max_size());
598  v.resize(s);
599  for (size_t i = 0; i < s; ++i)
600  svalue >> v[i];
601  if (svalue.fail()) {
602  std::stringstream msg;
603  msg << "string2val: unable to convert '" << str << "'";
604  throw std::invalid_argument(msg.str());
605  }
606  return v;
607  }
608 };
609 
610 
611 template <>
612 struct dispatch_attr_string<std::vector<bool> > {
613  static std::string val2string(const std::vector<bool>& value) {
614  std::stringstream sval;
615  sval << value.size();
616  for (size_t i = 0; i < value.size(); ++i)
617  sval << " " << value[i];
618  return sval.str();
619  }
620  static std::vector<bool> string2val(const std::string& str) {
621  size_t s;
622  std::istringstream svalue(str);
623  svalue >> s;
624  std::vector<bool> v(s);
625  for (size_t i = 0; i < s; ++i) {
626  bool value;
627  svalue >> value;
628  v[i] = value;
629  }
630  if (svalue.fail()) {
631  std::stringstream msg;
632  msg << "string2val: unable to convert '" << str << "'";
633  throw std::invalid_argument(msg.str());
634  }
635  return v;
636  }
637 };
638 
639 template <>
640 struct dispatch_attr_string<unsigned char> {
641  static std::string val2string(unsigned char value) {
642  std::stringstream sval;
643  sval << (unsigned int)value;
644  return sval.str();
645  }
646  static unsigned char string2val(const std::string& str) {
647  unsigned int v;
648  std::istringstream svalue(str);
649  svalue >> v;
650  return (unsigned char)v;
651  }
652 };
653 
654 template <>
655 struct dispatch_attr_string<signed char> {
656  static std::string val2string(signed char value) {
657  std::stringstream sval;
658  sval << (signed int)value;
659  return sval.str();
660  }
661  static signed char string2val(const std::string& str) {
662  int v;
663  std::istringstream svalue(str);
664  svalue >> v;
665  return (signed char)v;
666  }
667 };
668 
669 template <>
670 struct dispatch_attr_string<std::string> {
671  static std::string val2string(std::string value) {
672  return value;
673  }
674  static std::string string2val(const std::string& str) {
675  return str;
676  }
677 };
678 
679 template <>
680 struct dispatch_attr_string<CAttributeMap> {
681  static std::string val2string(const CAttributeMap& /*value*/) {
682  throw std::invalid_argument("Conversion of a CAttributeMap to a string not implemented");
683  }
684  static CAttributeMap string2val(const std::string& /*str*/) {
685  throw std::invalid_argument("Conversion of a string to a CAttributeMap not implemented");
686  }
687 };
688 
690 
691 template <typename T>
692 void CAttributedData::set_attribute(const std::string& key, const T& value)
693 {
694  add_attribute(*m_attr, key, value);
695 }
696 
697 
698 template <typename T>
699 std::string TAttribute<T>::do_as_string() const
700 {
701  return dispatch_attr_string<T>::val2string(m_value);
702 }
703 
704 template <typename T>
705 bool TAttribute<T>::do_is_equal(const CAttribute& other) const
706 {
707  const TAttribute<T>* o = dynamic_cast<const TAttribute<T> *>(&other);
708  if (!o) {
709  cvdebug() << "TAttribute<T>::do_is_equal:Cast to "
710  << typeid(const TAttribute<T>*).name()
711  << "failed\n";
712  return false;
713  }
714  return m_value == o->m_value;
715 }
716 
717 template <typename T>
718 bool TAttribute<T>::do_is_less(const CAttribute& other) const
719 {
720  const TAttribute<T>* o = dynamic_cast<const TAttribute<T> *>(&other);
721  if (o)
722  return m_value < o->m_value;
723 
724  return strcmp(typedescr(), other.typedescr()) < 0;
725 }
726 
727 template <typename T>
728 const T CAttributedData::get_attribute_as(const std::string& key)const
729 {
730  PAttribute attr = get_attribute(key);
731  if (attr)
732  return dynamic_cast<const TAttribute<T>&>(*attr);
733  else
734  throw create_exception<std::invalid_argument>("CAttributedData: no attribute '", key, "' found");
735 }
736 
737 template <typename T>
738 const T CAttributedData::get_attribute_as(const std::string& key, T default_value)const
739 {
740  PAttribute pattr = get_attribute(key);
741  if (!pattr)
742  return default_value;
743  auto attr = dynamic_cast<const TAttribute<T> *>(pattr.get());
744  if (!attr) {
745  cvwarn() << "Attribute '" << key << "'exists but is not of the expected type, returning default\n";
746  return default_value;
747  }
748  return *attr;
749 }
750 
751 
754 
757 
758 #ifdef LONG_64BIT
761 
764 #endif
765 
768 
771 
774 
777 
780 
783 
786 
788 
789 #endif
TAttribute< std::vector< double > > CVDoubleAttribute
a vector of doubles attribute
Definition: attributes.hh:196
virtual const char * typedescr() const
Definition: attributes.hh:542
T EXPORT_CORE get_attribute_as(const CAttribute &attr)
Definition: attributes.hh:157
CDebugSink & cvdebug()
Definition: msgstream.hh:216
TTranslator< std::vector< float > > CVFloatTranslator
Definition: attributes.hh:756
TTranslator< std::vector< unsigned long > > CVULTranslator
Definition: attributes.hh:760
TTranslator< unsigned long > CULTranslator
Definition: attributes.hh:759
Generic string vs. attribute translator singleton.
Definition: attributes.hh:507
bool operator==(const CAttribute &a, const CAttribute &b)
Definition: attributes.hh:91
TTranslator< std::vector< signed int > > CVSITranslator
Definition: attributes.hh:770
static CStringAttrTranslatorMap & instance()
TAttribute< std::string > CStringAttribute
a string attribute
Definition: attributes.hh:203
TTranslator< unsigned int > CUITranslator
Definition: attributes.hh:766
virtual const char * typedescr() const =0
static const int attr_unknown
virtual int type_id() const
Definition: attributes.hh:548
TAttribute< CAttributeMap > CAttributeList
providing the possibility to nest attribute lists
Definition: attributes.hh:227
TTranslator< std::vector< signed long > > CVSLTranslator
Definition: attributes.hh:763
TTranslator< std::vector< unsigned char > > CVUBTranslator
Definition: attributes.hh:779
TAttribute< int > CIntAttribute
an integer attribute
Definition: attributes.hh:166
The class of all attributes of data that is considered to ve meta-data.
Definition: attributes.hh:49
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:43
TAttribute< double > CDoubleAttribute
a double attribute
Definition: attributes.hh:190
A collection of attributes.
Definition: attributes.hh:253
std::string as_string() const
returns the value as a atring
TAttribute< std::vector< int > > CVIntAttribute
a vector of integers attribute
Definition: attributes.hh:172
TTranslator< signed int > CSITranslator
Definition: attributes.hh:769
virtual ~CAttrTranslator()
The virtual destructor just ensures virtual destruction and silences a warning.
Definition: attributes.hh:410
std::shared_ptr< CAttribute > PAttribute
define the shared pointer wrapped attribute pointer
Definition: attributes.hh:98
TAttribute< std::vector< float > > CVFloatAttribute
Definition: attributes.hh:184
TTranslator< std::vector< bool > > CVBitTranslator
Definition: attributes.hh:785
PAttribute to_attr(const std::string &key, const std::string &value) const
TTranslator< signed short > CSSTranslator
Definition: attributes.hh:775
void set_attribute(const std::string &key, PAttribute attr)
TAttribute< float > CFloatAttribute
a float attribute
Definition: attributes.hh:178
A class to translate an attribute from a string.
Definition: attributes.hh:407
const T get_attribute_as(const std::string &key) const
Definition: attributes.hh:728
TAttribute< std::vector< std::string > > CVStringAttribute
a vector of strings attribute
Definition: attributes.hh:209
TTranslator< double > CDoubleTranslator
Definition: attributes.hh:752
A singelton class to translate strings to attributes based on keys.
Definition: attributes.hh:437
TTranslator< bool > CBitTranslator
Definition: attributes.hh:784
TTranslator< std::vector< signed char > > CVSBTranslator
Definition: attributes.hh:782
const T & get_value() const
Definition: attributes.hh:536
TTranslator< std::vector< unsigned short > > CVUSTranslator
Definition: attributes.hh:773
TTranslator< unsigned char > CUBTranslator
Definition: attributes.hh:778
vstream & cvwarn()
send warnings to this stream adapter
Definition: msgstream.hh:311
bool is_equal(const CAttribute &other) const
void print(std::ostream &os) const
Definition: attributes.hh:373
void EXPORT_CORE add_attribute(CAttributeMap &attributes, const std::string &key, T value)
Definition: attributes.hh:479
#define EXPORT_CORE
Macro to manage Visual C++ style dllimport/dllexport.
Definition: defines.hh:110
virtual int type_id() const =0
TTranslator< signed long > CSLTranslator
Definition: attributes.hh:762
std::map< std::string, PAttribute > CAttributeMap
A name:attribute map.
Definition: attributes.hh:215
TTranslator< std::vector< unsigned int > > CVUITranslator
Definition: attributes.hh:767
TTranslator< float > CFloatTranslator
Definition: attributes.hh:755
TTranslator< std::vector< double > > CVDoubleTranslator
Definition: attributes.hh:753
TTranslator< signed char > CSBTranslator
Definition: attributes.hh:781
TTranslator< unsigned short > CUSTranslator
Definition: attributes.hh:772
std::ostream & operator<<(std::ostream &os, const CAttribute &attr)
Definition: attributes.hh:86
std::shared_ptr< CAttributeMap > PAttributeMap
another pointer-usage easy maker
Definition: attributes.hh:233
TAttribute(typename::boost::reference_wrapper< T >::type value)
Definition: attributes.hh:524
TTranslator< std::vector< signed short > > CVSSTranslator
Definition: attributes.hh:776
Class of an attribute that holds data of type T.
Definition: attributes.hh:114
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:46
bool from_string(const char *s, T &result)
Definition: tools.hh:78