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-2014 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>
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 
74  virtual int type_id() const = 0;
75 private:
76  virtual std::string do_as_string() const = 0;
77 
78  virtual bool do_is_equal(const CAttribute& other) const = 0;
79 
80  virtual bool do_is_less(const CAttribute& other) const = 0;
81 };
82 
83 
84 inline
85 std::ostream& operator << (std::ostream& os, const CAttribute& attr) {
86  os << attr.as_string();
87  return os;
88 };
89 
90 inline bool operator == (const CAttribute& a, const CAttribute& b)
91 {
92  return a.is_equal(b);
93 }
94 
95 
97 typedef std::shared_ptr<CAttribute > PAttribute;
98 
112 template <typename T>
114 public:
116 
117 
121  TAttribute(typename ::boost::reference_wrapper<T>::type value);
123 
124 
129  operator T()const;
130 
132  virtual const char *typedescr() const;
133 
134  virtual int type_id() const;
135 protected:
137  const T& get_value() const;
138 private:
139  virtual std::string do_as_string() const;
140  virtual bool do_is_equal(const CAttribute& other) const;
141  virtual bool do_is_less(const CAttribute& other) const;
142 
143  T m_value;
144 };
145 
155 template <typename T>
157  const TAttribute<T>& a = dynamic_cast<const TAttribute<T>&>(attr);
158  return a;
159 }
160 
166 
172 
178 
184 
190 
196 
197 
203 
209 
214 typedef std::map<std::string, PAttribute> CAttributeMap;
215 
216 template <>
218  static const int value = 1000;
219 };
220 
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 
311 
318  template <typename T>
319  void set_attribute(const std::string& key, const T& value);
320 
326  void set_attribute(const std::string& key, const char* value);
327 
328 
330  const std::string get_attribute_as_string(const std::string& key)const;
331 
332 
340  template <typename T>
341  const T get_attribute_as(const std::string& key)const;
342 
351  template <typename T>
352  const T get_attribute_as(const std::string& key, T default_value)const;
353 
359  void delete_attribute(const std::string& key);
360 
366  bool has_attribute(const std::string& key)const;
367 
369  friend EXPORT_CORE bool operator == (const CAttributedData& a, const CAttributedData& b);
371 
372  void print(std::ostream& os) const {
373  os << *m_attr;
374  }
375 private:
376  PAttributeMap m_attr;
377 };
378 
379 
380 inline std::ostream& operator << (std::ostream& os, const CAttributedData& data)
381 {
382  data.print(os);
383  return os;
384 }
385 
386 
387 
396 EXPORT_CORE bool operator == (const CAttributeMap& am, const CAttributeMap& bm);
397 
398 
407 public:
409  virtual ~CAttrTranslator() {};
410 
415  PAttribute from_string(const std::string& value) const;
416 private:
417  virtual PAttribute do_from_string(const std::string& value) const = 0;
418 protected:
419  CAttrTranslator();
420 
425  bool do_register(const std::string& key);
426 };
427 
437 public:
445  PAttribute to_attr(const std::string& key, const std::string& value) const;
446 
448  static CStringAttrTranslatorMap& instance();
449 private:
450  friend class CAttrTranslator;
459  bool add(const std::string& key, CAttrTranslator * t);
460 
461  typedef std::map<std::string, std::shared_ptr<CAttrTranslator>> CMap;
462  CMap m_translators;
463 };
464 
465 
477 template <typename T>
478 void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, T value)
479 {
480  cvdebug() << "add attribute " << key << " of type " << typeid(T).name() << " and value '" << value << "'\n";
481  attributes[key] = PAttribute(new TAttribute<T>(value));
482 }
483 
484 template <>
485 inline void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, const char *value)
486 {
487  attributes[key] = CStringAttrTranslatorMap::instance().to_attr(key, value);
488  cvdebug() << "add_attribute '" << key
489  << "' to '" << value << "' of type '"
490  << attributes[key]->typedescr() << "'\n";
491 }
492 
493 
494 
505 template <typename T>
507 public:
514  static bool register_for(const std::string& key);
515 private:
516  virtual PAttribute do_from_string(const std::string& value) const;
517 };
518 
519 
520 // template implementation
521 
522 template <typename T>
523 TAttribute<T>::TAttribute(typename ::boost::reference_wrapper<T>::type value):
524  m_value(value)
525 {
526 }
527 
528 template <typename T>
530 {
531  return m_value;
532 }
533 
534 template <typename T>
535 const T& TAttribute<T>::get_value() const
536 {
537  return m_value;
538 }
539 
540 template <typename T>
541 const char *TAttribute<T>::typedescr() const
542 {
543  return typeid(T).name();
544 }
545 
546 template <typename T>
548 {
550  "You must provide a type specialization for attribute_type<T>");
551 
552  return attribute_type<T>::value;
553 }
554 
563 template <typename T>
564 struct dispatch_attr_string {
565  static std::string val2string(const typename ::boost::reference_wrapper<T>::type value) {
566  std::stringstream sval;
567  sval << value;
568  return sval.str();
569  }
570  static T string2val(const std::string& str) {
571  T v;
572  std::istringstream svalue(str);
573  svalue >> v;
574  return v;
575  }
576 };
577 
578 
579 template <typename T>
580 struct dispatch_attr_string<std::vector<T> > {
581  static std::string val2string(const std::vector<T>& value) {
582  std::stringstream sval;
583  sval << value.size();
584  for (size_t i = 0; i < value.size(); ++i)
585  sval << " " << value[i];
586  return sval.str();
587  }
588  static std::vector<T> string2val(const std::string& str) {
589  size_t s;
590  std::istringstream svalue(str);
591  std::vector<T> v;
592  svalue >> s;
593  if (s > v.max_size())
594  throw create_exception<std::runtime_error>("string2val: try to create a vector of size ",
595  s, " but support only size ", v.max_size());
596  v.resize(s);
597  for (size_t i = 0; i < s; ++i)
598  svalue >> v[i];
599  if (svalue.fail()) {
600  std::stringstream msg;
601  msg << "string2val: unable to convert '" << str << "'";
602  throw std::invalid_argument(msg.str());
603  }
604  return v;
605  }
606 };
607 
608 
609 template <>
610 struct dispatch_attr_string<std::vector<bool> > {
611  static std::string val2string(const std::vector<bool>& value) {
612  std::stringstream sval;
613  sval << value.size();
614  for (size_t i = 0; i < value.size(); ++i)
615  sval << " " << value[i];
616  return sval.str();
617  }
618  static std::vector<bool> string2val(const std::string& str) {
619  size_t s;
620  std::istringstream svalue(str);
621  svalue >> s;
622  std::vector<bool> v(s);
623  for (size_t i = 0; i < s; ++i) {
624  bool value;
625  svalue >> value;
626  v[i] = value;
627  }
628  if (svalue.fail()) {
629  std::stringstream msg;
630  msg << "string2val: unable to convert '" << str << "'";
631  throw std::invalid_argument(msg.str());
632  }
633  return v;
634  }
635 };
636 
637 template <>
638 struct dispatch_attr_string<unsigned char> {
639  static std::string val2string(unsigned char value) {
640  std::stringstream sval;
641  sval << (unsigned int)value;
642  return sval.str();
643  }
644  static unsigned char string2val(const std::string& str) {
645  unsigned int v;
646  std::istringstream svalue(str);
647  svalue >> v;
648  return (unsigned char)v;
649  }
650 };
651 
652 template <>
653 struct dispatch_attr_string<signed char> {
654  static std::string val2string(signed char value) {
655  std::stringstream sval;
656  sval << (signed int)value;
657  return sval.str();
658  }
659  static signed char string2val(const std::string& str) {
660  int v;
661  std::istringstream svalue(str);
662  svalue >> v;
663  return (signed char)v;
664  }
665 };
666 
667 template <>
668 struct dispatch_attr_string<std::string> {
669  static std::string val2string(std::string value) {
670  return value;
671  }
672  static std::string string2val(const std::string& str) {
673  return str;
674  }
675 };
676 
677 template <>
678 struct dispatch_attr_string<CAttributeMap> {
679  static std::string val2string(const CAttributeMap& /*value*/) {
680  throw std::invalid_argument("Conversion of a CAttributeMap to a string not implemented");
681  }
682  static CAttributeMap string2val(const std::string& /*str*/) {
683  throw std::invalid_argument("Conversion of a string to a CAttributeMap not implemented");
684  }
685 };
686 
688 
689 template <typename T>
690 void CAttributedData::set_attribute(const std::string& key, const T& value)
691 {
692  add_attribute(*m_attr, key, value);
693 }
694 
695 
696 template <typename T>
697 std::string TAttribute<T>::do_as_string() const
698 {
699  return dispatch_attr_string<T>::val2string(m_value);
700 }
701 
702 template <typename T>
703 bool TAttribute<T>::do_is_equal(const CAttribute& other) const
704 {
705  const TAttribute<T>* o = dynamic_cast<const TAttribute<T> *>(&other);
706  if (!o) {
707  cvdebug() << "TAttribute<T>::do_is_equal:Cast to "
708  << typeid(const TAttribute<T>*).name()
709  << "failed\n";
710  return false;
711  }
712  return m_value == o->m_value;
713 }
714 
715 template <typename T>
716 bool TAttribute<T>::do_is_less(const CAttribute& other) const
717 {
718  const TAttribute<T>* o = dynamic_cast<const TAttribute<T> *>(&other);
719  if (o)
720  return m_value < o->m_value;
721 
722  return strcmp(typedescr(), other.typedescr()) < 0;
723 }
724 
725 template <typename T>
726 bool TTranslator<T>::register_for(const std::string& key)
727 {
728  TTranslator<T> * me = new TTranslator<T>();
729  if (!me->do_register(key)) {
730  delete me;
731  return false;
732  }
733  return true;
734 }
735 
736 template <typename T>
737 PAttribute TTranslator<T>::do_from_string(const std::string& value) const
738 {
739  return PAttribute(new TAttribute<T>(dispatch_attr_string<T>::string2val(value)));
740 }
741 
742 template <typename T>
743 const T CAttributedData::get_attribute_as(const std::string& key)const
744 {
745  PAttribute attr = get_attribute(key);
746  if (attr)
747  return dynamic_cast<const TAttribute<T>&>(*attr);
748  else
749  throw create_exception<std::invalid_argument>("CAttributedData: no attribute '", key, "' found");
750 }
751 
752 template <typename T>
753 const T CAttributedData::get_attribute_as(const std::string& key, T default_value)const
754 {
755  PAttribute pattr = get_attribute(key);
756  if (!pattr)
757  return default_value;
758  auto attr = dynamic_cast<const TAttribute<T> *>(pattr.get());
759  if (!attr) {
760  cvwarn() << "Attribute '" << key << "'exists but is not of the expected type, returning default\n";
761  return default_value;
762  }
763  return *attr;
764 }
765 
766 
769 
772 
773 #ifdef LONG_64BIT
776 
779 #endif
780 
783 
786 
789 
792 
795 
798 
801 
803 
804 #endif
TAttribute< std::vector< double > > CVDoubleAttribute
a vector of doubles attribute
Definition: attributes.hh:195
virtual const char * typedescr() const
Definition: attributes.hh:541
T EXPORT_CORE get_attribute_as(const CAttribute &attr)
Definition: attributes.hh:156
CDebugSink & cvdebug()
Definition: msgstream.hh:216
TTranslator< std::vector< float > > CVFloatTranslator
Definition: attributes.hh:771
TTranslator< std::vector< unsigned long > > CVULTranslator
Definition: attributes.hh:775
TTranslator< unsigned long > CULTranslator
Definition: attributes.hh:774
Generic string vs. attribute translator singleton.
Definition: attributes.hh:506
bool operator==(const CAttribute &a, const CAttribute &b)
Definition: attributes.hh:90
TTranslator< std::vector< signed int > > CVSITranslator
Definition: attributes.hh:785
static CStringAttrTranslatorMap & instance()
TAttribute< std::string > CStringAttribute
a string attribute
Definition: attributes.hh:202
TTranslator< unsigned int > CUITranslator
Definition: attributes.hh:781
virtual const char * typedescr() const =0
static const int attr_unknown
virtual int type_id() const
Definition: attributes.hh:547
TAttribute< CAttributeMap > CAttributeList
providing the possibility to nest attribute lists
Definition: attributes.hh:226
TTranslator< std::vector< signed long > > CVSLTranslator
Definition: attributes.hh:778
TTranslator< std::vector< unsigned char > > CVUBTranslator
Definition: attributes.hh:794
TAttribute< int > CIntAttribute
an integer attribute
Definition: attributes.hh:165
The class of all attributes of data that is considered to ve meta-data.
Definition: attributes.hh:48
static bool register_for(const std::string &key)
Definition: attributes.hh:726
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:43
TAttribute< double > CDoubleAttribute
a double attribute
Definition: attributes.hh:189
A collection of attributes.
Definition: attributes.hh:252
std::string as_string() const
returns the value as a atring
TAttribute< std::vector< int > > CVIntAttribute
a vector of integers attribute
Definition: attributes.hh:171
TTranslator< signed int > CSITranslator
Definition: attributes.hh:784
virtual ~CAttrTranslator()
The virtual destructor just ensures virtual destruction and silences a warning.
Definition: attributes.hh:409
std::shared_ptr< CAttribute > PAttribute
define the shared pointer wrapped attribute pointer
Definition: attributes.hh:97
TAttribute< std::vector< float > > CVFloatAttribute
Definition: attributes.hh:183
TTranslator< std::vector< bool > > CVBitTranslator
Definition: attributes.hh:800
PAttribute to_attr(const std::string &key, const std::string &value) const
TTranslator< signed short > CSSTranslator
Definition: attributes.hh:790
void set_attribute(const std::string &key, PAttribute attr)
TAttribute< float > CFloatAttribute
a float attribute
Definition: attributes.hh:177
A class to translate an attribute from a string.
Definition: attributes.hh:406
const T get_attribute_as(const std::string &key) const
Definition: attributes.hh:743
TAttribute< std::vector< std::string > > CVStringAttribute
a vector of strings attribute
Definition: attributes.hh:208
TTranslator< double > CDoubleTranslator
Definition: attributes.hh:767
static const int value
A singelton class to translate strings to attributes based on keys.
Definition: attributes.hh:436
TTranslator< bool > CBitTranslator
Definition: attributes.hh:799
TTranslator< std::vector< signed char > > CVSBTranslator
Definition: attributes.hh:797
const T & get_value() const
Definition: attributes.hh:535
TTranslator< std::vector< unsigned short > > CVUSTranslator
Definition: attributes.hh:788
TTranslator< unsigned char > CUBTranslator
Definition: attributes.hh:793
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:372
void EXPORT_CORE add_attribute(CAttributeMap &attributes, const std::string &key, T value)
Definition: attributes.hh:478
#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:777
std::map< std::string, PAttribute > CAttributeMap
A name:attribute map.
Definition: attributes.hh:214
const PAttribute get_attribute(const std::string &key) const
TTranslator< std::vector< unsigned int > > CVUITranslator
Definition: attributes.hh:782
TTranslator< float > CFloatTranslator
Definition: attributes.hh:770
TTranslator< std::vector< double > > CVDoubleTranslator
Definition: attributes.hh:768
bool do_register(const std::string &key)
TTranslator< signed char > CSBTranslator
Definition: attributes.hh:796
TTranslator< unsigned short > CUSTranslator
Definition: attributes.hh:787
std::ostream & operator<<(std::ostream &os, const CAttribute &attr)
Definition: attributes.hh:85
std::shared_ptr< CAttributeMap > PAttributeMap
another pointer-usage easy maker
Definition: attributes.hh:232
TAttribute(typename::boost::reference_wrapper< T >::type value)
Definition: attributes.hh:523
TTranslator< std::vector< signed short > > CVSSTranslator
Definition: attributes.hh:791
Class of an attribute that holds data of type T.
Definition: attributes.hh:113
#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