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-2017 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 <type_traits>
35 #include <iomanip>
36 #include <boost/any.hpp>
37 #include <boost/ref.hpp>
38 #include <boost/lexical_cast.hpp>
40 
42 
52 public:
54  virtual ~CAttribute();
55 
57  std::string as_string() const;
58 
63  bool is_equal(const CAttribute& other) const;
64 
71  bool is_less(const CAttribute& other) const;
72 
74  virtual const char *typedescr() const = 0;
75 
77  virtual int type_id() const = 0;
78 private:
79  virtual std::string do_as_string() const = 0;
80 
81  virtual bool do_is_equal(const CAttribute& other) const = 0;
82 
83  virtual bool do_is_less(const CAttribute& other) const = 0;
84 };
85 
86 
87 inline
88 std::ostream& operator << (std::ostream& os, const CAttribute& attr) {
89  os << attr.as_string();
90  return os;
91 };
92 
93 inline bool operator == (const CAttribute& a, const CAttribute& b)
94 {
95  return a.is_equal(b);
96 }
97 
98 
100 typedef std::shared_ptr<CAttribute > PAttribute;
101 
115 template <typename T>
117 public:
119 
120 
124  TAttribute(typename ::boost::reference_wrapper<T>::type value);
126 
127 
132  operator T()const;
133 
135  virtual const char *typedescr() const;
136 
137  virtual int type_id() const;
138 protected:
140  const T& get_value() const;
141 private:
142  virtual std::string do_as_string() const;
143  virtual bool do_is_equal(const CAttribute& other) const;
144  virtual bool do_is_less(const CAttribute& other) const;
145 
146  T m_value;
147 };
148 
158 template <typename T>
160  const TAttribute<T>& a = dynamic_cast<const TAttribute<T>&>(attr);
161  return a;
162 }
163 
169 
175 
181 
187 
193 
199 
200 
206 
212 
217 typedef std::map<std::string, PAttribute> CAttributeMap;
218 
219 template <>
221  static const int value = 1000;
222 };
223 
224 
230 
235 typedef std::shared_ptr<CAttributeMap > PAttributeMap;
236 
237 
245 EXPORT_CORE std::ostream& operator << (std::ostream& os, const CAttributeMap& data);
246 
247 
256 public:
257 
259 
260 
261  CAttributedData();
262  CAttributedData(const CAttributedData& org);
263 
269 
271 
273  CAttributedData& operator =(const CAttributedData& org);
274 
279  const PAttribute get_attribute(const std::string& key) const;
280 
284  CAttributeMap::const_iterator begin_attributes() const;
285 
289  CAttributeMap::const_iterator end_attributes() const;
290 
297  void set_attribute(const std::string& key, PAttribute attr);
298 
299 
305  void set_attributes(CAttributeMap::const_iterator begin, CAttributeMap::const_iterator end);
306 
312  void set_attribute(const std::string& key, const std::string& value);
313 
314 
321  template <typename T>
322  void set_attribute(const std::string& key, const T& value);
323 
329  void set_attribute(const std::string& key, const char* value);
330 
331 
333  const std::string get_attribute_as_string(const std::string& key)const;
334 
335 
343  template <typename T>
344  const T get_attribute_as(const std::string& key)const;
345 
354  template <typename T>
355  const T get_attribute_as(const std::string& key, T default_value)const;
356 
362  void delete_attribute(const std::string& key);
363 
369  bool has_attribute(const std::string& key)const;
370 
372  friend EXPORT_CORE bool operator == (const CAttributedData& a, const CAttributedData& b);
374 
375  void print(std::ostream& os) const {
376  os << *m_attr;
377  }
378 private:
379  PAttributeMap m_attr;
380 };
381 
382 
383 inline std::ostream& operator << (std::ostream& os, const CAttributedData& data)
384 {
385  data.print(os);
386  return os;
387 }
388 
389 
390 
399 EXPORT_CORE bool operator == (const CAttributeMap& am, const CAttributeMap& bm);
400 
401 
410 public:
412  virtual ~CAttrTranslator() {};
413 
418  PAttribute from_string(const std::string& value) const;
419 private:
420  virtual PAttribute do_from_string(const std::string& value) const = 0;
421 protected:
422  CAttrTranslator();
423 
428  bool do_register(const std::string& key);
429 };
430 
440 public:
448  PAttribute to_attr(const std::string& key, const std::string& value) const;
449 
451  static CStringAttrTranslatorMap& instance();
452 private:
453  friend class CAttrTranslator;
462  bool add(const std::string& key, CAttrTranslator * t);
463 
464  typedef std::map<std::string, std::shared_ptr<CAttrTranslator>> CMap;
465  CMap m_translators;
466 };
467 
468 
480 template <typename T>
481 void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, T value)
482 {
483  cvdebug() << "add attribute " << key << " of type " << typeid(T).name() << " and value '" << value << "'\n";
484  attributes[key] = PAttribute(new TAttribute<T>(value));
485 }
486 
487 template <>
488 inline void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, const char *value)
489 {
490  attributes[key] = CStringAttrTranslatorMap::instance().to_attr(key, value);
491  cvdebug() << "add_attribute '" << key
492  << "' to '" << value << "' of type '"
493  << attributes[key]->typedescr() << "'\n";
494 }
495 
496 
497 
508 template <typename T>
510 public:
517  static bool register_for(const std::string& key);
518 private:
519  virtual PAttribute do_from_string(const std::string& value) const;
520 };
521 
522 
523 // template implementation
524 
525 template <typename T>
526 TAttribute<T>::TAttribute(typename ::boost::reference_wrapper<T>::type value):
527  m_value(value)
528 {
529 }
530 
531 template <typename T>
533 {
534  return m_value;
535 }
536 
537 template <typename T>
538 const T& TAttribute<T>::get_value() const
539 {
540  return m_value;
541 }
542 
543 template <typename T>
544 const char *TAttribute<T>::typedescr() const
545 {
546  return typeid(T).name();
547 }
548 
549 template <typename T>
551 {
553  "You must provide a type specialization for attribute_type<T>");
554 
555  return attribute_type<T>::value;
556 }
557 
566 template <typename T, bool is_floating>
567 struct __convert_to_string
568 {
569  static std::string apply(const typename ::boost::reference_wrapper<T>::type value) {
570  return boost::lexical_cast<std::string>(value);
571  }
572 };
573 
574 template <typename T>
575 struct __convert_to_string<T, true> {
576  static std::string apply(const typename ::boost::reference_wrapper<T>::type value) {
577  std::stringstream sval;
578  sval << std::setprecision(10) << value;
579  return sval.str();
580  }
581 };
582 
583 
584 template <typename T>
585 struct dispatch_attr_string {
586  static std::string val2string(const typename ::boost::reference_wrapper<T>::type value) {
587  return __convert_to_string<T, std::is_floating_point<T>::value>::apply(value);
588  }
589  static T string2val(const std::string& str) {
590  T v;
591  std::istringstream svalue(str);
592  svalue >> v;
593  return v;
594  }
595 };
596 
597 
598 template <typename T>
599 struct dispatch_attr_string<std::vector<T> > {
600  static std::string val2string(const std::vector<T>& value) {
601  std::stringstream sval;
602  sval << value.size();
603  for (size_t i = 0; i < value.size(); ++i)
604  sval << " "
605  << __convert_to_string<T, std::is_floating_point<T>::value>::apply(value[i]);
606  return sval.str();
607  }
608  static std::vector<T> string2val(const std::string& str) {
609  size_t s;
610  std::istringstream svalue(str);
611  std::vector<T> v;
612  svalue >> s;
613  if (s > v.max_size())
614  throw create_exception<std::runtime_error>("string2val: try to create a vector of size ",
615  s, " but support only size ", v.max_size());
616  v.resize(s);
617  for (size_t i = 0; i < s; ++i)
618  svalue >> v[i];
619  if (svalue.fail()) {
620  std::stringstream msg;
621  msg << "string2val: unable to convert '" << str << "'";
622  throw std::invalid_argument(msg.str());
623  }
624  return v;
625  }
626 };
627 
628 
629 template <>
630 struct dispatch_attr_string<std::vector<bool> > {
631  static std::string val2string(const std::vector<bool>& value) {
632  std::stringstream sval;
633  sval << value.size();
634  for (size_t i = 0; i < value.size(); ++i)
635  sval << " " << value[i];
636  return sval.str();
637  }
638  static std::vector<bool> string2val(const std::string& str) {
639  size_t s;
640  std::istringstream svalue(str);
641  svalue >> s;
642  std::vector<bool> v(s);
643 
644  // Added override for coverity
645  //
646  // Since s is used as the size for the new vector, a large
647  // value will result in a std::bad_alloc exception. This
648  // is not worse than bailing out because s is larger than
649  // an abitrary set boundary that youle be cheked here.
650  //
651  // coverity[tainted_scalar]
652  for (size_t i = 0; i < s; ++i) {
653  bool value;
654  svalue >> value;
655  v[i] = value;
656  }
657  if (svalue.fail()) {
658  std::stringstream msg;
659  msg << "string2val: unable to convert '" << str << "'";
660  throw std::invalid_argument(msg.str());
661  }
662  return v;
663  }
664 };
665 
666 template <>
667 struct dispatch_attr_string<unsigned char> {
668  static std::string val2string(unsigned char value) {
669  std::stringstream sval;
670  sval << (unsigned int)value;
671  return sval.str();
672  }
673  static unsigned char string2val(const std::string& str) {
674  unsigned int v;
675  std::istringstream svalue(str);
676  svalue >> v;
677  return (unsigned char)v;
678  }
679 };
680 
681 template <>
682 struct dispatch_attr_string<signed char> {
683  static std::string val2string(signed char value) {
684  std::stringstream sval;
685  sval << (signed int)value;
686  return sval.str();
687  }
688  static signed char string2val(const std::string& str) {
689  int v;
690  std::istringstream svalue(str);
691  svalue >> v;
692  return (signed char)v;
693  }
694 };
695 
696 template <>
697 struct dispatch_attr_string<std::string> {
698  static std::string val2string(std::string value) {
699  return value;
700  }
701  static std::string string2val(const std::string& str) {
702  return str;
703  }
704 };
705 
706 template <>
707 struct dispatch_attr_string<CAttributeMap> {
708  static std::string val2string(const CAttributeMap& /*value*/) {
709  throw std::invalid_argument("Conversion of a CAttributeMap to a string not implemented");
710  }
711  static CAttributeMap string2val(const std::string& /*str*/) {
712  throw std::invalid_argument("Conversion of a string to a CAttributeMap not implemented");
713  }
714 };
715 
717 
718 template <typename T>
719 void CAttributedData::set_attribute(const std::string& key, const T& value)
720 {
721  add_attribute(*m_attr, key, value);
722 }
723 
724 
725 template <typename T>
726 std::string TAttribute<T>::do_as_string() const
727 {
728  return dispatch_attr_string<T>::val2string(m_value);
729 }
730 
731 template <typename T>
732 bool TAttribute<T>::do_is_equal(const CAttribute& other) const
733 {
734  const TAttribute<T>* o = dynamic_cast<const TAttribute<T> *>(&other);
735  if (!o) {
736  cvdebug() << "TAttribute<T>::do_is_equal:Cast to "
737  << typeid(const TAttribute<T>*).name()
738  << "failed\n";
739  return false;
740  }
741  return m_value == o->m_value;
742 }
743 
744 template <typename T>
745 bool TAttribute<T>::do_is_less(const CAttribute& other) const
746 {
747  const TAttribute<T>* o = dynamic_cast<const TAttribute<T> *>(&other);
748  if (o)
749  return m_value < o->m_value;
750 
751  return strcmp(typedescr(), other.typedescr()) < 0;
752 }
753 
754 template <typename T>
755 const T CAttributedData::get_attribute_as(const std::string& key)const
756 {
757  PAttribute attr = get_attribute(key);
758  if (attr)
759  return dynamic_cast<const TAttribute<T>&>(*attr);
760  else
761  throw create_exception<std::invalid_argument>("CAttributedData: no attribute '", key, "' found");
762 }
763 
764 template <typename T>
765 const T CAttributedData::get_attribute_as(const std::string& key, T default_value)const
766 {
767  PAttribute pattr = get_attribute(key);
768  if (!pattr)
769  return default_value;
770  auto attr = dynamic_cast<const TAttribute<T> *>(pattr.get());
771  if (!attr) {
772  cvwarn() << "Attribute '" << key << "'exists but is not of the expected type, returning default\n";
773  return default_value;
774  }
775  return *attr;
776 }
777 
778 
780 extern template class EXPORT_CORE TAttribute<uint8_t>;
781 extern template class EXPORT_CORE TAttribute<int8_t>;
782 
783 extern template class EXPORT_CORE TAttribute<std::vector<uint8_t> >;
784 extern template class EXPORT_CORE TAttribute<std::vector<int8_t> >;
786 
789 
792 
795 
798 
801 
804 
807 
810 
813 
816 
819 
821 
822 #endif
TAttribute< std::vector< double > > CVDoubleAttribute
a vector of doubles attribute
Definition: attributes.hh:198
virtual int type_id() const
Definition: attributes.hh:550
T EXPORT_CORE get_attribute_as(const CAttribute &attr)
Definition: attributes.hh:159
void print(std::ostream &os) const
Definition: attributes.hh:375
CDebugSink & cvdebug()
Definition: msgstream.hh:216
TTranslator< std::vector< float > > CVFloatTranslator
Definition: attributes.hh:791
TTranslator< std::vector< int64_t > > CVSLTranslator
Definition: attributes.hh:797
TTranslator< uint8_t > CUBTranslator
Definition: attributes.hh:811
Generic string vs. attribute translator singleton.
Definition: attributes.hh:509
bool operator==(const CAttribute &a, const CAttribute &b)
Definition: attributes.hh:93
static CStringAttrTranslatorMap & instance()
TAttribute< std::string > CStringAttribute
a string attribute
Definition: attributes.hh:205
TTranslator< unsigned int > CUITranslator
Definition: attributes.hh:799
const T & get_value() const
Definition: attributes.hh:538
TTranslator< int64_t > CSLTranslator
Definition: attributes.hh:796
virtual const char * typedescr() const =0
static const int attr_unknown
TAttribute< CAttributeMap > CAttributeList
providing the possibility to nest attribute lists
Definition: attributes.hh:229
TAttribute< int > CIntAttribute
an integer attribute
Definition: attributes.hh:168
The class of all attributes of data that is considered to ve meta-data.
Definition: attributes.hh:51
bool is_equal(const CAttribute &other) const
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
TAttribute< double > CDoubleAttribute
a double attribute
Definition: attributes.hh:192
A collection of attributes.
Definition: attributes.hh:255
TTranslator< std::vector< int8_t > > CVSBTranslator
Definition: attributes.hh:815
TAttribute< std::vector< int > > CVIntAttribute
a vector of integers attribute
Definition: attributes.hh:174
TTranslator< signed int > CSITranslator
Definition: attributes.hh:802
virtual ~CAttrTranslator()
The virtual destructor just ensures virtual destruction and silences a warning.
Definition: attributes.hh:412
std::shared_ptr< CAttribute > PAttribute
define the shared pointer wrapped attribute pointer
Definition: attributes.hh:100
TAttribute< std::vector< float > > CVFloatAttribute
Definition: attributes.hh:186
TTranslator< std::vector< uint8_t > > CVUBTranslator
Definition: attributes.hh:812
const T get_attribute_as(const std::string &key) const
Definition: attributes.hh:755
TTranslator< std::vector< bool > > CVBitTranslator
Definition: attributes.hh:818
void set_attribute(const std::string &key, PAttribute attr)
TTranslator< std::vector< int32_t > > CVSITranslator
Definition: attributes.hh:803
TAttribute< float > CFloatAttribute
a float attribute
Definition: attributes.hh:180
A class to translate an attribute from a string.
Definition: attributes.hh:409
TTranslator< int8_t > CSBTranslator
Definition: attributes.hh:814
TTranslator< std::vector< int16_t > > CVSSTranslator
Definition: attributes.hh:809
NEVER typedef TTranslator< double > CDoubleTranslator
*/
Definition: attributes.hh:787
TTranslator< uint64_t > CULTranslator
Definition: attributes.hh:793
TAttribute< std::vector< std::string > > CVStringAttribute
a vector of strings attribute
Definition: attributes.hh:211
std::string as_string() const
returns the value as a atring
A singelton class to translate strings to attributes based on keys.
Definition: attributes.hh:439
TTranslator< bool > CBitTranslator
Definition: attributes.hh:817
PAttribute to_attr(const std::string &key, const std::string &value) const
TAttribute(typename ::boost::reference_wrapper< T >::type value)
Definition: attributes.hh:526
TTranslator< uint16_t > CUSTranslator
Definition: attributes.hh:805
vstream & cvwarn()
send warnings to this stream adapter
Definition: msgstream.hh:311
void EXPORT_CORE add_attribute(CAttributeMap &attributes, const std::string &key, T value)
Definition: attributes.hh:481
#define EXPORT_CORE
Macro to manage Visual C++ style dllimport/dllexport.
Definition: defines.hh:101
virtual int type_id() const =0
std::map< std::string, PAttribute > CAttributeMap
A name:attribute map.
Definition: attributes.hh:217
TTranslator< int16_t > CSSTranslator
Definition: attributes.hh:808
TTranslator< std::vector< uint64_t > > CVULTranslator
Definition: attributes.hh:794
TTranslator< float > CFloatTranslator
Definition: attributes.hh:790
TTranslator< std::vector< uint32_t > > CVUITranslator
Definition: attributes.hh:800
TTranslator< std::vector< double > > CVDoubleTranslator
Definition: attributes.hh:788
std::ostream & operator<<(std::ostream &os, const CAttribute &attr)
Definition: attributes.hh:88
virtual const char * typedescr() const
Definition: attributes.hh:544
std::shared_ptr< CAttributeMap > PAttributeMap
another pointer-usage easy maker
Definition: attributes.hh:235
Class of an attribute that holds data of type T.
Definition: attributes.hh:116
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36
TTranslator< std::vector< uint16_t > > CVUSTranslator
Definition: attributes.hh:806
bool from_string(const char *s, T &result)
Definition: tools.hh:78