MIRA
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Class.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
48 #ifndef _MIRA_CLASS_H_
49 #define _MIRA_CLASS_H_
50 
51 #include <vector>
52 #include <map>
53 #include <cstdarg>
54 
55 #ifndef Q_MOC_RUN
56 #include <boost/shared_ptr.hpp>
57 #endif
58 
59 #include <thread/Thread.h>
60 #include <platform/Typename.h>
61 #include <utils/Foreach.h>
62 #include <error/Exception.h>
64 #include <factory/TypeId.h>
65 #include <factory/Object.h>
66 
67 
68 namespace mira {
69 
71 
72 class Class;
73 class ClassProxy;
74 class Object;
75 
76 typedef ClassProxy ClassPtr;
77 
78 template <typename CLASS>
79 inline CLASS* mira_factoryDynamicCast( Object* base );
80 
82 
83 MIRA_DEFINE_EXCEPTION(XFactoryUnknown, Exception)
84 MIRA_DEFINE_EXCEPTION(XFactoryLogical, Exception)
85 MIRA_DEFINE_EXCEPTION(XFactoryBadCast, Exception)
86 
87 // *****************************************************************************
88 // *** Class
89 // *****************************************************************************
90 
98 {
99  friend class ClassFactory;
100 
101  template<typename CLASS>
102  friend class TClass;
103  friend class ClassProxy;
104 
105 public:
106  virtual ~Class();
107 
112  virtual std::string const& getIdentifier() const;
113 
120  virtual std::string const& getName() const;
121 
127  virtual int getTypeId() const = 0;
128 
132  virtual Typename getTypename() const = 0;
133 
138  std::map<std::string, std::string> const& getMetaInfo() const;
139 
145  std::string const& getMetaInfo(const std::string& meta) const;
146 
154  virtual Object* newInstance() const = 0;
155 
163  template <class CLASS>
164  CLASS* newInstance() const;
165 
176  virtual Object* newInstance( int paramCount, ... ) const = 0;
177 
185  virtual Object* newInstance( std::string const& childIdentifier ) const = 0;
186 
194  template <class CLASS>
195  CLASS* newInstance( std::string const& childIdentifier ) const;
196 
207  virtual Object* newInstance( std::string const& childIdentifier,
208  int paramCount, ... ) const = 0;
209 
213  bool isClassRegistered( std::string const& classIdentifier ) const;
214 
220  void eraseChild( Class const* const iClass );
221 
227  void eraseParent( Class const* const iClass );
228 
233  ClassProxy getClassByIdentifier(
234  std::string const& classIdentifier ) const;
235 
240  std::vector<ClassProxy> getClassByMeta( std::string const& metaKey,
241  std::string const& metaValue ) const;
242 
250  template <class T>
251  std::vector<ClassProxy> getClassByMeta( T funcPtr ) const;
252 
256  std::map<std::string, ClassProxy> getDerivedClasses() const;
257 
261  std::map<std::string, ClassProxy> getDirectParents() const;
262 
266  bool isBaseOf( Class const* const derived ) const;
267 
271  bool isBaseOf( ClassProxy derived ) const;
272 
276  bool isBaseOf( std::string const& identifier ) const;
277 
281  bool isDerivedFrom( Class const* const base ) const;
282 
286  bool isDerivedFrom( ClassProxy base ) const;
287 
291  bool isDirectlyDerivedFrom( Class const* const base ) const;
292 
296  bool isDirectlyDerivedFrom( ClassProxy base ) const;
297 
302  bool isDeclaredAbstract() const;
303 
307  virtual bool isAbstract() const = 0;
308 
314  bool isLibraryLoaded() const;
315 
317 
324  template<typename Reflector>
325  void reflectRead( Reflector& r );
326 
333  template<typename Reflector>
334  void reflectWrite( Reflector& r );
335 
339  bool operator==(Class const& other) const {
340  return this == &other;
341  }
342 
346  bool operator!=(Class const& other) const {
347  return this != &other;
348  }
349 
353  bool operator <(Class const& other ) const {
354  return mIdentifier < other.mIdentifier;
355  }
356 
357 protected:
362  virtual Object* newVAInstance( int paramCount, std::va_list ) const = 0;
363 
367  Class( std::string const& identifier,
368  std::string const& name,
369  std::map<std::string, std::string> const& metaInfo,
370  bool libLoaded );
371 
375  Class ( std::string const& identifier, std::string const& name,
376  bool libLoaded );
377 
378 private:
382  Class() {}
383 
384 protected:
385  std::map<std::string, ClassProxy > mDerivedChildren;
386  std::map<std::string, ClassProxy> mDirectParents;
387  std::string mIdentifier;
388  std::string mName;
389  std::string mLib;
390  std::map<std::string, std::string> mMetaInfo;
391  bool mLibLoaded;
392 };
393 
401 {
402  friend class ClassFactory;
403  friend class VacantClass;
404  friend class Class;
405 
406  template<typename CLASS>
407  friend class TClass;
408 
409 public:
410  ClassProxy() : mClass( NULL ), mThreadMutex( NULL )
411  {
412  }
413 
414  ClassProxy( ClassProxy const& other )
415  {
416  mClass = other.mClass;
417  mThreadMutex = other.mThreadMutex;
418  }
419 
420  bool operator== (ClassProxy const& other ) const {
421  if ( !mClass || !*mClass || !other.mClass || !*other.mClass )
422  MIRA_THROW( XFactoryLogical, "ClassProxy invalid!" );
423  return **other.mClass == **mClass;
424  }
425 
426  bool operator!= (ClassProxy const& other ) const {
427  if ( !mClass || !*mClass || !other.mClass || !*other.mClass )
428  MIRA_THROW( XFactoryLogical, "ClassProxy invalid!" );
429  return **other.mClass != **mClass;
430  }
431 
432  bool operator <(ClassProxy const& other ) const {
433  if ( !mClass || !*mClass || !other.mClass || !*other.mClass )
434  MIRA_THROW( XFactoryLogical, "ClassProxy invalid!" );
435  return **mClass < **other.mClass;
436  }
437 
442  std::string const& getIdentifier() const;
443 
448  std::string const& getName() const;
449 
454  int getTypeId() const;
455 
460  Typename getTypename() const;
461 
466  std::map<std::string, std::string> const& getMetaInfo() const;
467 
472  std::string const& getMetaInfo(const std::string& meta) const;
473 
478  Object* newInstance() const;
479 
484  template <class CLASS>
485  CLASS* newInstance() const
486  {
487  boost::recursive_mutex::scoped_lock lock( *mThreadMutex );
488  return (*mClass)->newInstance<CLASS>();
489  }
490 
495  Object* newInstance( int paramCount, ... ) const;
496 
501  Object* newInstance( std::string const& childIdentifier ) const;
502 
507  template <class CLASS>
508  CLASS* newInstance( std::string const& childIdentifier ) const
509  {
510  boost::recursive_mutex::scoped_lock lock( *mThreadMutex );
511  return (*mClass)->newInstance<CLASS>( childIdentifier );
512  }
513 
518  Object* newInstance( std::string const& childIdentifier,
519  int paramCount, ... ) const;
520 
525  bool isClassRegistered( std::string const& classIdentifier ) const;
526 
532  void eraseChild( Class const* const iClass );
533 
539  void eraseParent( Class const* const iClass );
540 
545  ClassProxy getClassByIdentifier(std::string const& classIdentifier ) const;
546 
551  std::vector<ClassProxy> getClassByMeta(std::string const& metaKey,
552  std::string const& metaValue ) const;
553 
558  template <class T>
559  std::vector<ClassProxy> getClassByMeta( T funcPtr ) const
560  {
561  boost::recursive_mutex::scoped_lock lock( *mThreadMutex );
562  return (*mClass)->getClassByMeta( funcPtr );
563  }
564 
569  std::map<std::string, ClassProxy > getDerivedClasses() const;
570 
575  std::map<std::string, ClassProxy > getDirectParents() const;
576 
581  bool isBaseOf( Class const* const derived ) const;
582 
587  bool isBaseOf( ClassProxy derived ) const;
588 
593  bool isBaseOf( std::string const& identifier ) const;
594 
599  bool isDerivedFrom( Class const* const base ) const;
600 
605  bool isDerivedFrom( ClassProxy base ) const;
606 
611  bool isDirectlyDerivedFrom( Class const* const base ) const;
612 
617  bool isDirectlyDerivedFrom( ClassProxy base ) const;
618 
622  bool isAbstract() const;
623 
629  bool isLibraryLoaded() const;
630 
631 protected:
632  Object* newVAInstance( int paramCount, std::va_list list ) const;
633 
634  ClassProxy( boost::shared_ptr<Class>* iClass );
635  void setClass( boost::shared_ptr<Class>* iClass );
636 
637 protected:
638  boost::shared_ptr<Class>* mClass;
639  boost::recursive_mutex* mThreadMutex;
640 };
641 
643 
644 // *****************************************************************************
645 // *** ClassFactoryAbstractClassBuilder
646 // *****************************************************************************
647 
652 struct ClassFactoryAbstractClassBuilder {
653 
654  template<typename CLASS>
655  static CLASS* invoke( ) {
656  MIRA_THROW( XFactoryLogical, "Cannot create abstract class ("
657  + CLASS::CLASS().getIdentifier() + ")!" );
658  return NULL;
659  }
660 
661  template<int N, typename CLASS>
662  static CLASS* invoke( std::va_list ) {
663  MIRA_THROW( XFactoryLogical, "Cannot create abstract class ("
664  + CLASS::CLASS().getIdentifier() + ")!" );
665  return NULL;
666  }
667 };
668 
669 // *****************************************************************************
670 // *** ClassFactoryNoDefaultConstClassBuilder
671 // *****************************************************************************
672 
678 struct ClassFactoryNoDefaultConstClassBuilder {
679  template<typename CLASS>
680  static CLASS* invoke( ) {
681  MIRA_THROW( XFactoryLogical, "No public default constructor available for class"
682  "creation (" + CLASS::CLASS().getIdentifier() + ")!" );
683  // go home
684  return NULL;
685  }
686 };
687 
688 // *****************************************************************************
689 // *** ClassFactoryDefaultConstClassBuilder
690 // *****************************************************************************
691 
698 struct ClassFactoryDefaultConstClassBuilder {
699 
700  template<typename CLASS>
701  static CLASS* invoke( ) {
702  return new CLASS;
703  }
704 
705  template<int N, typename CLASS>
706  static CLASS* invoke( std::va_list ) {
707  MIRA_THROW( XFactoryLogical, "Desired parameter constructor not registered ("
708  + CLASS::CLASS().getIdentifier() + ")!" );
709  return NULL;
710  }
711 };
712 
714 
715 // *****************************************************************************
716 // *** Class implementation
717 // *****************************************************************************
718 
719 template <class CLASS>
720 inline CLASS* mira::Class::newInstance() const
721 {
722  Object* tBase = newInstance();
723  return mira_factoryDynamicCast<CLASS>( tBase );
724 }
725 
726 template <class CLASS>
727 inline CLASS* mira::Class::newInstance( std::string const& childIdentifier ) const
728 {
729  Object* tBase = newInstance( childIdentifier );
730  return mira_factoryDynamicCast<CLASS>( tBase );
731 }
732 
733 template <class T>
734 inline std::vector<ClassProxy> mira::Class::getClassByMeta( T funcPtr ) const
735 {
736  std::vector<ClassProxy> tReturn;
737  // apply matching function for each registered child
738  std::map<std::string, ClassProxy >::const_iterator tIt = mDerivedChildren.begin();
739  for( ; tIt != mDerivedChildren.end(); tIt++ ) {
740  if ( funcPtr( tIt->second.getMetaInfo() ) ) {
741  tReturn.push_back( tIt->second );
742  }
743  }
744  return tReturn;
745 }
746 
747 
748 
749 
750 template<typename Reflector>
751 inline void mira::Class::reflectRead(Reflector& r)
752 {
753  r.member( "Identifier" , mIdentifier, "" );
754  r.member( "Name" , mName, "" );
755  r.member( "Lib" , mLib, "" );
756  r.member( "Meta" , mMetaInfo, "" );
757  bool tAbstract = isAbstract();
758  r.member( "Abstract", tAbstract, "" );
759 }
760 
761 template<typename Reflector>
762 inline void mira::Class::reflectWrite(Reflector& r)
763 {
764  r.member( "Identifier" , mIdentifier, "" );
765  r.member( "Name" , mName, "" );
766  r.member( "Lib" , mLib, "" );
767  r.member( "Meta" , mMetaInfo, "" );
768 }
769 
774 template <typename CLASS>
775 inline CLASS* mira_factoryDynamicCast( Object* base )
776 {
777  CLASS* tClass = dynamic_cast<CLASS*> ( base );
778  if ( !tClass ) {
779  std::string tName = "NULL";
780  if ( base ) {
781  tName = base->getClass().getIdentifier();
782  }
783  delete base;
784  MIRA_THROW( XFactoryBadCast, "You try to cast created object to incompatible"
785  " base class (" + tName + ")!");
786  }
787  return tClass;
788 }
789 
791 
792 } // namespace
793 
794 #endif /* _MIRA_CLASS_H_ */
795 
Macro for iterating over all elements in a container.
void reflectWrite(Reflector &r, Buffer< T, Allocator > &c)
Specialization of the non-intrusive reflect for Buffer.
Definition: Buffer.h:581
#define MIRA_DEFINE_EXCEPTION(Ex, Base)
Macro for easily defining a new compatible exception class.
Definition: Exception.h:175
void reflectWrite(Reflector &r)
Implementation of class member reflection.
Definition: Class.h:762
CLASS * mira_factoryDynamicCast(Object *base)
Auxiliary function which throws an XFactoryBadCast exception if the cast fails and deletes the object...
Definition: Class.h:775
What should i say, the class factory.
Definition: Factory.h:89
The class proxy assures that the pointer to the class object is always valid.
Definition: Class.h:400
bool operator<(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:231
ClassProxy ClassPtr
Definition: Class.h:74
std::vector< ClassProxy > getClassByMeta(T funcPtr) const
Return vector of Class objects returning true for the given.
Definition: Class.h:559
std::string Typename
Definition: Typename.h:59
#define MIRA_SPLIT_REFLECT_MEMBER
Macro that insert a class member reflect() method just splitting reflection into a reflectRead() and ...
Definition: SplitReflect.h:238
Class object which supports some kind of class reflection.
Definition: Class.h:97
bool operator!=(Class const &other) const
Returns true, if the two classes are not identical.
Definition: Class.h:346
bool operator==(Class const &other) const
Returns true, if the two classes are identical.
Definition: Class.h:339
Get compiler and platform independent typenames.
Provides MIRA_SPLIT_REFLECT macros.
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:91
Class const & getClass() const
call the virtual internalGetClass().
Definition: Object.h:159
MIRA_SPLIT_REFLECT_MEMBER void reflectRead(Reflector &r)
Implementation of class member reflection.
std::string mName
class name
Definition: Class.h:388
Includes, defines and functions for threads.
boost::recursive_mutex * mThreadMutex
Definition: Class.h:639
virtual std::string const & getIdentifier() const
Return identifier for the class.
CLASS * newInstance() const
Return a new instance of the class associated with the class object.
Definition: Class.h:485
bool mLibLoaded
is associated lib loaded?
Definition: Class.h:391
std::string mLib
lib name
Definition: Class.h:389
The object class acts as a generic base class for classes which should be used with the classFactory...
Definition: Object.h:144
bool operator==(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:225
The VacantClass object is the implementation of the Class class for classes which are NOT available s...
Definition: VacantClass.h:68
std::map< std::string, std::string > mMetaInfo
meta info of class
Definition: Class.h:390
std::vector< ClassProxy > getClassByMeta(std::string const &metaKey, std::string const &metaValue) const
Return vector of ClassProxy objects matching the meta criterion.
Base class for exceptions.
Definition: Exception.h:204
std::map< std::string, ClassProxy > mDerivedChildren
map of children
Definition: Class.h:385
CLASS * newInstance(std::string const &childIdentifier) const
Return a new instance of the child class with the given identifier.
Definition: Class.h:508
void reflectRead(Reflector &r, Buffer< T, Allocator > &c)
Specialization of the non-intrusive reflect for Buffer.
Definition: Buffer.h:565
ClassProxy(ClassProxy const &other)
Definition: Class.h:414
The TClass object is the implementation of the class class for classes which are available since the ...
Definition: TClass.h:75
$Defines object class as base class for classFactory compatible classes$.
boost::shared_ptr< Class > * mClass
Definition: Class.h:638
bool operator!=(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:228
#define MIRA_BASE_EXPORT
This is required because on windows there is a macro defined called ERROR.
Definition: Platform.h:153
std::string mIdentifier
class identifier
Definition: Class.h:387
Provides method for generating a unique id for any type.
std::map< std::string, ClassProxy > mDirectParents
map of parents
Definition: Class.h:386
Exception base class.
virtual Object * newInstance() const =0
Return a new instance of the class associated with the class object.
Definition: Class.h:720
ClassProxy()
Definition: Class.h:410