//================================================================================================== // S t a n d a r d Interface // C l a s s // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides facilities to manage classes. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "standard/class.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guStandardClass #define guStandardClass
// Headers //--------------------------------------------------------------------------------------- #include <cstring> /*INCLUDE*/ #include <string> /*INCLUDE*/ #include <utility> /*INCLUDE*/ #include <bpp/standard/environment.hpp> /*INCLUDE*/ #include <bpp/standard/type.hpp> /*INCLUDE*/
#ifdef USE_SYMBOL_DEMANGLING #include <contribution/demangle.hpp> #endif
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef STANDARD_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area standardClass #define private_area standardClass_private
namespace public_area { /*NAMESPACE*/ using namespace standardType; } namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //--------------------------------------------------------------------------------
// Macrocommands //--------------------------------------------------------------------------------- /*MACROCOMMAND*/ /* Provides a <I>slot</I> for a given method. A slot is a nested class (without any code) with a name similar to the name of the original method (<CODE>_slot</CODE> is appended to the original name). Thus it allows to associate a static identifier with a method. This is useful when the method pointer needs to be given as a template parameter: instead of giving the method pointer (that is not a global reference), the associated static identifier (i.e. the method slot) is provided. */ #define add_method_slot(prMethod) public_property class prMethod##_slot {}
/*MACROCOMMAND*/ /* Provides the slot of a given method. */ #define method_slot(prClass,prMethod) prClass::prMethod##_slot
/*MACROCOMMAND*/ /* Provides the unique number (from a given reference) assigned to a method. */ #define method_no(prReference,prClass,prMethod) \ (clMethodInformation< prReference,prClass,method_slot(prClass,prMethod) >::index().value()) \
/*MACROCOMMAND*/ /* Provides the unique number (from a given reference) assigned to a class. */ #define class_no(prReference,prClass) (clClassInformation< prReference,prClass >::index().value())
/*MACROCOMMAND*/ /* Declares a class indexer inside a reference class. */ #define class_indexer(prReference) \ friend class clClassIndexer<prReference>; \ \ private_property static tcString clClassIndexer_atClassNameS[CLASS_NUMBERING_SIZE]; \ private_property static tyCardinal clClassIndexer_atNbClass; \ private_property static tyCardinal clClassIndexer_atNbMethodS[CLASS_NUMBERING_SIZE]; \ \ read_write_static_attribute(clClassIndexer<prReference>,atClassIndexer,classIndexer) \
/*MACROCOMMAND*/ /* Creates the class indexer of a reference class. */ #define static_class_indexer(prReference) \ tcString prReference::clClassIndexer_atClassNameS[CLASS_NUMBERING_SIZE]; \ tyCardinal prReference::clClassIndexer_atNbClass = 0; \ tyCardinal prReference::clClassIndexer_atNbMethodS[CLASS_NUMBERING_SIZE]; \ clClassIndexer<prReference> prReference::atClassIndexer \
/*MACROCOMMAND*/ /* Wraps a type into a class. See the <code>TypeWrapper</code> class for details. */ #define type_wrapper(prType) bpp::standardClass::clTypeWrapper< prType >::clType
// Types & Classes //------------------------------------------------------------------------------- namespace public_area { //------------------------------------------------------------------------------------------Classes class clBaseObject;
template <class prReference,class prClass> class clClassIndex; template <class prReference> class clClassIndexer; template <class prReference,class prClass> class clClassInformation; template <class prReference,class prClass> class clMethodIndex; template <class prReference,class prClass,class prMethod> class clMethodInformation; template <class prType> class clTypeWrapper; template <int prVersion> class clVersion; //-----------------------------------------------------------------------------------Constant Types typedef const clBaseObject ctBaseObject; }
namespace private_area {}
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { std::string demangleSymbol(tcString); std::string demangleType(tcString);
#ifdef NEED_COMPLEMENTARY_COMPARATORS template <class prObject1,class prObject2> tyBoolean operator != (const prObject1 &,const prObject2 &);
template <class prObject1,class prObject2> tyBoolean operator > (const prObject1 &,const prObject2 &);
template <class prObject1,class prObject2> tyBoolean operator <= (const prObject1 &,const prObject2 &);
template <class prObject1,class prObject2> tyBoolean operator >= (const prObject1 &,const prObject2 &); #endif
template <class prKey,class prElement> inline std::pair<prKey,prElement> make_pair(const prKey &,const prElement &); }
namespace private_area { testing_mode ( function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- extern_dynamic_constant(private,clMutex,goDemangleMutex,?);
// B a s e O b j e c t Interface //---------------------------------------------------------------- namespace public_area { /*CLASS clBaseObject */ /* Defines the base class of all the other classes. */ class clBaseObject { //-----------------------------------------------------------------------------------------Private private_property constructor clBaseObject(ctBaseObject &); private_property clBaseObject & operator = (ctBaseObject &); //------------------------------------------------------------------------------------------Public public_property constructor clBaseObject(void); public_property virtual destructor clBaseObject(void); }; }
// C l a s s I n d e x e r Interface //------------------------------------------------------------ namespace public_area { /*CLASS clClassIndexer */ /* Represents the indexer of a set of classes. It is used to assign unique numbers to classes and their methods. The numbering is a continuous sequence of indexes, starting from 0, so it is possible to store and access quickly data for the classes and their methods (through vectors for instance). An indexer must be located inside a class, called the <I>reference</I> for all the information that the class indexer and its associated classes (<CODE>clClassInformation</CODE> and <CODE>clMethodInformation</CODE>) can provide. */ template <class prReference> class clClassIndexer : public clBaseObject { //-----------------------------------------------------------------------------------------Private private_property constructor clClassIndexer(const clClassIndexer &); private_property clClassIndexer & operator = (const clClassIndexer &); //------------------------------------------------------------------------------------------Public public_property constructor clClassIndexer(void); public_property destructor clClassIndexer(void);
public_property tcString className(tyCardinal) const; public_property tyCardinal nbClass(void) const; public_property tyCardinal nbMethod(tyCardinal) const;
public_property tyCardinal getClassNo(ctTypeInformation &); public_property tyCardinal getMethodNo(ctTypeInformation &); }; }
// C l a s s I n d e x Interface //---------------------------------------------------------------- namespace public_area { /*CLASS clClassIndex */ /* Represents the index of a class according to a given reference. */ template <class prReference,class prClass> class clClassIndex : public clBaseObject { //-----------------------------------------------------------------------------------------Private private_property constructor clClassIndex(const clClassIndex &); private_property clClassIndex & operator = (const clClassIndex &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clClassIndex */ /* Value of the index. */ read_only_attribute(tyCardinal,atValue,value);
public_property constructor clClassIndex(void); public_property destructor clClassIndex(void); }; }
// M e t h o d I n d e x Interface //-------------------------------------------------------------- namespace public_area { /*CLASS clMethodIndex */ /* Represents the index of a class according to a given reference. */ template <class prReference,class prClass> class clMethodIndex : public clBaseObject { //-----------------------------------------------------------------------------------------Private private_property constructor clMethodIndex(const clMethodIndex &); private_property clMethodIndex & operator = (const clMethodIndex &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clMethodIndex */ /* Value of the index. */ read_only_attribute(tyCardinal,atValue,value);
public_property constructor clMethodIndex(void); public_property destructor clMethodIndex(void); }; }
// C l a s s I n f o r m a t i o n Interface //---------------------------------------------------- namespace public_area { /*CLASS clClassInformation */ /* Represents information (from a given reference) about a class. This class can not be instantiated. */ template <class prReference,class prClass> class clClassInformation : public clBaseObject { //-------------------------------------------------------------------------------------------Types /*TYPE clClassInformation */ /* Type of the index of the class. */ public_property typedef clClassIndex<prReference,prClass> cpIndex; //-----------------------------------------------------------------------------------------Private private_property constructor clClassInformation(void); private_property constructor clClassInformation(const clClassInformation &); private_property clClassInformation & operator = (const clClassInformation &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clClassInformation */ /* Index of the class. */ read_only_static_attribute(cpIndex,atIndex,index); }; }
// M e t h o d I n f o r m a t i o n Interface //-------------------------------------------------- namespace public_area { /*CLASS clMethodInformation */ /* Represents information (from a given reference) about a method. The last parameter <CODE>prMethod</CODE> is not a pointer on the method, but a <I>slot</I> (it is a static identifier the user must associate with the method, see the <CODE>add_method_slot</CODE> macrocommand for details). This class can not be instantiated. */ template <class prReference,class prClass,class prMethod> class clMethodInformation : public clBaseObject { //-------------------------------------------------------------------------------------------Types /*TYPE clMethodInformation */ /* Type of the index of the method. */ public_property typedef clMethodIndex<prReference,prClass> cpIndex; //-----------------------------------------------------------------------------------------Private private_property constructor clMethodInformation(void); private_property constructor clMethodInformation(const clMethodInformation &); private_property clMethodInformation & operator = (const clMethodInformation &); //------------------------------------------------------------------------------------------Public /*ATTRIBUTE clMethodInformation */ /* Index of the method. */ read_only_static_attribute(cpIndex,atIndex,index); }; }
// T y p e W r a p p e r Interface //-------------------------------------------------------------- namespace public_area { /*CLASS clTypeWrapper */ /* Wraps a type into a class. It is useful to manipulate a complex type expression (like a function pointer) as a single expression. Abstract class. */ template <class prType> class clTypeWrapper { //-------------------------------------------------------------------------------------------Types /*TYPE clTypeWrapper */ /* Type of the parameter of the template. */ public_property typedef prType clType; //------------------------------------------------------------------------------------------Public public_property virtual ~clTypeWrapper(void) = 0; }; }
// V e r s i o n Interface //---------------------------------------------------------------------- namespace public_area { /*CLASS clVersion */ /* Represents a version of an algorithm. Necessary to manipulate an algorithm that has several implementations. */ template <int prVersion> class clVersion : public clBaseObject { //-----------------------------------------------------------------------------------------Private private_property constructor clVersion(const clVersion &); private_property clVersion & operator = (const clVersion &); //------------------------------------------------------------------------------------------Public public_property constructor clVersion(void); public_property virtual destructor clVersion(void); }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area { #ifdef NEED_COMPLEMENTARY_COMPARATORS //-------------------------------------------------------------------------------------Operator != template <class prObject1,class prObject2> inline tyBoolean operator != (const prObject1 & agObject1,const prObject2 & agObject2) { return (not (agObject1==agObject2)); } //--------------------------------------------------------------------------------------Operator > template <class prObject1,class prObject2> inline tyBoolean operator > (const prObject1 & agObject1,const prObject2 & agObject2) { return (agObject2<agObject1); } //-------------------------------------------------------------------------------------Operator <= template <class prObject1,class prObject2> inline tyBoolean operator <= (const prObject1 & agObject1,const prObject2 & agObject2) { return (not (agObject2<agObject1)); } //-------------------------------------------------------------------------------------Operator >= template <class prObject1,class prObject2> inline tyBoolean operator >= (const prObject1 & agObject1,const prObject2 & agObject2) { return (not (agObject1<agObject2)); } #endif
//----------------------------------------------------------------------------------------Make_pair /*FUNCTION*/ /* For efficiency reasons, the <CODE>make_pair</CODE> of the STL is rewritten. This version is for general purpose (do not use it with STL maps, or for any structure that uses pairs where the first element's type is constant). */ template <class prKey,class prElement> inline std::pair<prKey,prElement> make_pair(const prKey & agKey,const prElement & agElement) { return (std::pair<prKey,prElement>(agKey,agElement)); } }
namespace private_area {}
// B a s e O b j e c t Inline //------------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clBaseObject */ /* Default constructor. */ inline clBaseObject::clBaseObject(void) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clBaseObject */ /* Destructor. */ inline clBaseObject::~clBaseObject(void) {} }
// C l a s s I n d e x e r Inline //--------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clClassIndexer */ /* Builds a class indexer. */ template <class prReference> inline clClassIndexer<prReference>::clClassIndexer(void) : clBaseObject() {} //---------------------------------------------------------------------------------------Destructor /*METHOD clClassIndexer */ /* Destructs the class indexer. */ template <class prReference> inline clClassIndexer<prReference>::~clClassIndexer(void) {} //----------------------------------------------------------------------------------------ClassName /*METHOD clClassIndexer */ /* Returns the name of a class indexed by the object. */ template <class prReference> inline tcString clClassIndexer<prReference>::className(tyCardinal agClassNo) const { return (prReference::clClassIndexer_atClassNameS[agClassNo]); } //------------------------------------------------------------------------------------------NbClass /*METHOD clClassIndexer */ /* Returns the number of classes indexed by the object. */ template <class prReference> inline tyCardinal clClassIndexer<prReference>::nbClass(void) const { return (prReference::clClassIndexer_atNbClass); } //-----------------------------------------------------------------------------------------NbMethod /*METHOD clClassIndexer */ /* Returns the number of methods of a given class indexed by the object. */ template <class prReference> inline tyCardinal clClassIndexer<prReference>::nbMethod(tyCardinal agClassNo) const { return (prReference::clClassIndexer_atNbMethodS[agClassNo]); } //--------------------------------------------------------------------------------------GetMethodNo /*METHOD clClassIndexer */ /* Gets a new method number in the continuous sequence of indexes of a given class. <B>Do not call directly this method.</B> Use instead the <CODE>clMethodInformation</CODE> class to get the number of a method. */ template <class prReference> inline tyCardinal clClassIndexer<prReference>::getMethodNo(ctTypeInformation & agClassInformation) { return ((prReference::clClassIndexer_atNbMethodS[getClassNo(agClassInformation)])++); } }
// V e r s i o n Inline //------------------------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clVersion */ /* Default constructor. */ template <int prVersion> inline clVersion<prVersion>::clVersion(void) : clBaseObject() {} //---------------------------------------------------------------------------------------Destructor /*METHOD clVersion */ /* Destructor. */ template <int prVersion> inline clVersion<prVersion>::~clVersion(void) {} }
// C l a s s I n d e x e r Implementation //------------------------------------------------------- namespace public_area { //---------------------------------------------------------------------------------------GetClassNo /*METHOD clClassIndexer */ /* Gets a new class number in the continuous sequence of indexes. <B>Do not call directly this method.</B> Use instead the <CODE>clClassInformation</CODE> class to get the number of a class. */ template <class prReference> tyCardinal clClassIndexer<prReference>::getClassNo(ctTypeInformation & agClassInformation) { typedef tcString tyClassNameS[CLASS_NUMBERING_SIZE];
tyClassNameS & lcClassNameS = prReference::clClassIndexer_atClassNameS; tyCardinal lcCounter = 0; tcString lcName = agClassInformation.name(); tyCardinal & lcNbClass = prReference::clClassIndexer_atNbClass;
while (lcCounter<lcNbClass and strcmp(lcClassNameS[lcCounter],lcName)!=0) ++lcCounter;
if (lcCounter==lcNbClass) { ++lcNbClass; prReference::clClassIndexer_atNbMethodS[lcCounter]=0; lcClassNameS[lcCounter]=lcName; }
return (lcCounter); } }
// C l a s s I n d e x Implementation //----------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clClassIndex */ /* Builds a class index (i.e. gets a number to identify a class). */ template <class prReference,class prClass> clClassIndex<prReference,prClass>::clClassIndex(void) : clBaseObject(),atValue(prReference::classIndexer().getClassNo(typeid(prClass))) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clClassIndex */ /* Destructs the index. */ template <class prReference,class prClass> clClassIndex<prReference,prClass>::~clClassIndex(void) {} }
// M e t h o d I n d e x Implementation //--------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clMethodIndex */ /* Builds a method index (i.e. gets a number to identify a method). */ template <class prReference,class prClass> clMethodIndex<prReference,prClass>::clMethodIndex(void) : clBaseObject(),atValue(prReference::classIndexer().getMethodNo(typeid(prClass))) {} //---------------------------------------------------------------------------------------Destructor /*METHOD clMethodIndex */ /* Destructs the index. */ template <class prReference,class prClass> clMethodIndex<prReference,prClass>::~clMethodIndex(void) {} }
// C l a s s I n f o r m a t i o n Implementation //----------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------Static Attributes template <class prReference,class prClass> clClassIndex<prReference,prClass> clClassInformation<prReference,prClass>::atIndex; }
// M e t h o d I n f o r m a t i o n Implementation //--------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------Static Attributes template <class prReference,class prClass,class prMethod> clMethodIndex<prReference,prClass> clMethodInformation<prReference,prClass,prMethod>::atIndex; }
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef public_area #undef private_area #endif |
//================================================================================================== // S t a n d a r d Implementation // C l a s s // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "standard/class.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define STANDARD_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/standard/class.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area standardClass #define private_area standardClass_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Standard/Class");
// Initialization //--------------------------------------------------------------------------------
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- dynamic_constant(clMutex,goDemangleMutex);
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //-----------------------------------------------------------------------------------DemangleSymbol /*FUNCTION*/ /* Demangles the string representing the name of a symbol. */ function std::string demangleSymbol(tcString agString) { std::string lcString;
#ifdef USE_SYMBOL_DEMANGLING clMutex * lcMutex = private_area::goDemangleMutex;
if (lcMutex!=nil) lcMutex->lock(); libcw::debug::demangle_symbol(agString,lcString); if (lcMutex!=nil) lcMutex->release(); #else lcString=agString; #endif
return (lcString); } //-------------------------------------------------------------------------------------DemangleType /*FUNCTION*/ /* Demangles the string representing the name of a type. */ function std::string demangleType(tcString agString) { std::string lcString;
#ifdef USE_SYMBOL_DEMANGLING clMutex * lcMutex = private_area::goDemangleMutex;
if (lcMutex!=nil) lcMutex->lock(); libcw::debug::demangle_type(agString,lcString); if (lcMutex!=nil) lcMutex->release(); #else lcString=agString; #endif
return (lcString); } }
namespace private_area {}
// X X X Implementation //------------------------------------------------------------------------- namespace {}
// End //------------------------------------------------------------------------------------------- } |
|