mirror of https://github.com/KLayout/klayout.git
607 lines
15 KiB
C++
607 lines
15 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2017 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program 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 General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
#ifndef _HDR_gsiClassBase
|
|
#define _HDR_gsiClassBase
|
|
|
|
#include "tlObject.h"
|
|
#include "tlObjectCollection.h"
|
|
#include "tlException.h"
|
|
#include "tlExpression.h"
|
|
#include "tlAssert.h"
|
|
#include "tlHeap.h"
|
|
|
|
#include "gsiExpression.h"
|
|
#include "gsiObject.h"
|
|
#include "gsiSerialisation.h"
|
|
#include "gsiMethods.h"
|
|
|
|
#include <list>
|
|
#include <map>
|
|
#include <vector>
|
|
#include <typeinfo>
|
|
#include <memory>
|
|
|
|
namespace gsi
|
|
{
|
|
|
|
/**
|
|
* @brief A base class for client-specific data per class
|
|
*
|
|
* Objects of this type are used inside the ClassBase object to store
|
|
* information specific for certain clients.
|
|
*/
|
|
class PerClassClientSpecificData
|
|
{
|
|
public:
|
|
PerClassClientSpecificData ()
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
virtual ~PerClassClientSpecificData()
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief The basic object to declare a class
|
|
*
|
|
* This object represents a GSI class. It provides the methods to translate the typeless object
|
|
* pointer to a real C++ object and to perform some basic operations on the object.
|
|
* It also provides metainformation such as method declarations and similar.
|
|
*/
|
|
class GSI_PUBLIC ClassBase
|
|
: public tl::Object
|
|
{
|
|
public:
|
|
typedef tl::weak_collection<ClassBase> class_collection;
|
|
typedef class_collection::const_iterator class_iterator;
|
|
typedef Methods::iterator method_iterator;
|
|
|
|
/**
|
|
* @brief Constructor
|
|
*
|
|
* The constructor supplies information about the connector class (can be 0), a documentation string and the method declarations.
|
|
*/
|
|
ClassBase (const std::string &doc, const Methods &mm, bool do_register = true);
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
virtual ~ClassBase ();
|
|
|
|
/**
|
|
* @brief Gets the pointer to the base class declaration object (can be 0)
|
|
*/
|
|
const ClassBase *base () const
|
|
{
|
|
return mp_base;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns a pointer to the type_info object if the class is an adaptor
|
|
*
|
|
* If the class adapts another type (specifically enums), this method will
|
|
* return a pointer to the adapted type's type_info.
|
|
* In other cases, the return value is 0.
|
|
*/
|
|
virtual const std::type_info *adapted_type_info () const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the "real" (consolidated) declaration object
|
|
*
|
|
* The actual declaration object may be different from this declaration because of the class extension
|
|
* mechanism. Using that mechanism, class declarations can extend over multiple ClassBase objects. The
|
|
* individual declarations are merged and a consolidated class declaration object is provided.
|
|
*/
|
|
virtual const ClassBase *declaration () const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Consolidates the declaration
|
|
*
|
|
* Before all classes are finalized and the script interpreters start to instantiate them, all
|
|
* class declarations are consolidated. If the consolidate method returns true, the class declaration
|
|
* is kept. Otherwise it is discarded.
|
|
*/
|
|
virtual bool consolidate () const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the class name
|
|
*/
|
|
const std::string &name () const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the documentation string
|
|
*/
|
|
const std::string &doc () const
|
|
{
|
|
return m_doc;
|
|
}
|
|
|
|
/**
|
|
* @brief Merge base and extension declarations
|
|
*
|
|
* This method must be called at least once!
|
|
* It produces the consolidates class declaration object.
|
|
*/
|
|
static void merge_declarations ();
|
|
|
|
/**
|
|
* @brief Gets the parent declaration object
|
|
* This returns the parent class if this class is a child class.
|
|
*/
|
|
const ClassBase *parent () const
|
|
{
|
|
return mp_parent;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the fully qualified name (A::B::..)
|
|
*/
|
|
std::string qname () const;
|
|
|
|
/**
|
|
* @brief Adds a child class
|
|
*/
|
|
void add_child_class (const ClassBase *cls);
|
|
|
|
/**
|
|
* @brief Iterates all child classes (begin)
|
|
*/
|
|
tl::weak_collection<ClassBase>::const_iterator begin_child_classes () const
|
|
{
|
|
return m_child_classes.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates all subclasses (end)
|
|
*/
|
|
tl::weak_collection<ClassBase>::const_iterator end_child_classes () const
|
|
{
|
|
return m_child_classes.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates all classes present (begin)
|
|
*/
|
|
static class_iterator begin_classes ()
|
|
{
|
|
return collection ().begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates all classes present (end)
|
|
*/
|
|
static class_iterator end_classes ()
|
|
{
|
|
return collection ().end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates the methods (begin)
|
|
*/
|
|
method_iterator begin_methods () const
|
|
{
|
|
return m_methods.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates the methods (end)
|
|
*/
|
|
method_iterator end_methods () const
|
|
{
|
|
return m_methods.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates the constructor methods (begin)
|
|
*/
|
|
method_iterator begin_constructors () const
|
|
{
|
|
return m_constructors.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates the constructor methods (end)
|
|
*/
|
|
method_iterator end_constructors () const
|
|
{
|
|
return m_constructors.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates the callback methods (begin)
|
|
*/
|
|
method_iterator begin_callbacks () const
|
|
{
|
|
return m_callbacks.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterates the callback methods (end)
|
|
*/
|
|
method_iterator end_callbacks () const
|
|
{
|
|
return m_callbacks.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Returns true, if this class is derived from the given base class
|
|
*/
|
|
bool is_derived_from (const ClassBase *base) const;
|
|
|
|
/**
|
|
* @brief Returns true, if this class can be used to initialize an object with type "target"
|
|
*/
|
|
bool can_convert_to (const ClassBase *target) const;
|
|
|
|
/**
|
|
* @brief Creates a new object initialized from "obj" of type "target"
|
|
*/
|
|
void *create_obj_from (const ClassBase *target, void *obj) const;
|
|
|
|
/**
|
|
* @brief Class implementation: destroys the given object
|
|
*
|
|
* The implementation of this method is supposed to delete the object and
|
|
* free any resources associated with that object. After that operation,
|
|
* the object pointer is invalid.
|
|
*
|
|
* This method may not be available if "can_destroy" is false.
|
|
*/
|
|
virtual void destroy (void * /*obj*/) const
|
|
{
|
|
tl_assert (false);
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: creates an object (default constructor)
|
|
*
|
|
* Creates and default-initializes the given object. This method may not be
|
|
* available if there is no default constructor (can_default_create is false).
|
|
* In that case, some static factory method must be provided.
|
|
*/
|
|
virtual void *create () const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Creates a class representing an adapted object
|
|
*
|
|
* This method will create a new object representing the adapted object x.
|
|
*/
|
|
virtual void *create_from_adapted (const void * /*x*/) const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Creates a class representing an adapted object
|
|
*
|
|
* This method will create a new object representing the adapted object x.
|
|
* It will consume the object given by x.
|
|
*/
|
|
virtual void *create_from_adapted_consume (void * /*x*/) const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns a pointer to the adapted object from an adaptor class
|
|
*/
|
|
virtual const void *adapted_from_obj (const void * /*obj*/) const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns a new pointer to the adapted object from an adaptor class
|
|
*/
|
|
virtual void *create_adapted_from_obj (const void * /*obj*/) const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: clones the given object
|
|
*
|
|
* The implementation is supposed to create a deep copy of the source object.
|
|
* This method may not be available if can_copy is false.
|
|
*/
|
|
virtual void *clone (const void * /*src*/) const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: assigns the source to the target object
|
|
*
|
|
* The implementation is supposed to overwrite the target with the contents
|
|
* of the source. This is a deep copy.
|
|
* This method may not be available if can_copy is false.
|
|
*/
|
|
virtual void assign (void * /*target*/, const void * /*src*/) const
|
|
{
|
|
tl_assert (false);
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: destruction supported predicate
|
|
*
|
|
* This flag is true, if the class supports destruction of objects of this kind.
|
|
*/
|
|
virtual bool can_destroy () const
|
|
{
|
|
tl_assert (false);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: copy supported predicate
|
|
*
|
|
* This flag is true, if the class supports copying of objects of this kind.
|
|
*/
|
|
virtual bool can_copy () const
|
|
{
|
|
tl_assert (false);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: default construction supported predicate
|
|
*
|
|
* This flag is true, if the class supports default construction of objects of this kind.
|
|
*/
|
|
virtual bool can_default_create () const
|
|
{
|
|
tl_assert (false);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: check C++ type of object
|
|
*
|
|
* This method returns true, if objects of this class are compatible with
|
|
* the given C++ type.
|
|
*/
|
|
virtual bool is_of_type (const std::type_info & /*ti*/) const
|
|
{
|
|
tl_assert (false);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns true, if the given object can be cast to this class
|
|
*
|
|
* When this method is called, it is guaranteed that the object is at least of
|
|
* the base class type. This implies that there is a base class when this method
|
|
* is called.
|
|
*/
|
|
virtual bool can_upcast (const void * /*p*/) const
|
|
{
|
|
tl_assert (false);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: gets C++ type of object
|
|
*
|
|
* This method delivers the C++ type_info object of this class.
|
|
*/
|
|
virtual const std::type_info &type () const
|
|
{
|
|
tl_assert (false);
|
|
return typeid (void);
|
|
}
|
|
|
|
/**
|
|
* @brief Class implementation: gets C++ type of object
|
|
*
|
|
* This method delivers the class declaration for an subclassed object p. p must be of a
|
|
* subclass (derived class) of this class. This method will the declaration object
|
|
* of object p.
|
|
*/
|
|
virtual const ClassBase *subclass_decl (const void * /*p*/) const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Class Implementation: Returns true, if the object is managed
|
|
* "managed" objects are those which are derived from gsi::ObjectBase.
|
|
*/
|
|
virtual bool is_managed () const
|
|
{
|
|
tl_assert (false);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the basic gsi::ObjectBase object from a generic pointer
|
|
* This method will return 0, if the object is not managed.
|
|
* If required is false, a return value of 0 is permitted, indicating that
|
|
* no dynamic allocation of a gsi::ObjectBase has happened yet. This is useful
|
|
* in case of the Qt-GSI bridge which means a special Qt object needs to be
|
|
* created in order to provide the gsi::ObjectBase interface. If required is
|
|
* false, this initialization does not need to happen.
|
|
*/
|
|
virtual gsi::ObjectBase *gsi_object (void * /*p*/, bool /*required*/ = true) const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Class Implementation: provide variant binding information (constness)
|
|
*/
|
|
virtual const tl::VariantUserClassBase *var_cls (bool /*is_const*/) const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Class Implementation: provide variant binding information (meta/class object)
|
|
*/
|
|
virtual const tl::VariantUserClassBase *var_cls_cls () const
|
|
{
|
|
tl_assert (false);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Post-construction initialization
|
|
*
|
|
* This method will be called by the GSI system to provide initialization after
|
|
* the static initialization. Some schemes cannot be implementation statically, plus
|
|
* the initialization order is indetermined for static initialization.
|
|
* In that case, this initialization step is useful. It will call the initialize
|
|
* method on all method declarations.
|
|
*/
|
|
virtual void initialize ();
|
|
|
|
/**
|
|
* @brief Adds a method to the class
|
|
* The class becomes owner of the method object.
|
|
* This method is public to allow dynamic extension of the documentation
|
|
* through scripts.
|
|
* Don't use it for other purposes.
|
|
*/
|
|
void add_method (MethodBase *method, bool base_class = false);
|
|
|
|
/**
|
|
* @brief Sets the per-client data for the given client index
|
|
* This method is const to preserve the general const semantics of the class
|
|
* while allowing clients to register information.
|
|
*/
|
|
void set_data (int ch, PerClassClientSpecificData *data) const
|
|
{
|
|
mp_data[ch].reset (data);
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the per-client data for the given client index
|
|
*/
|
|
PerClassClientSpecificData *data (int ch) const
|
|
{
|
|
return mp_data[ch].get ();
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the per-client data for gsi::Expressions
|
|
* This is a special slot since no client index is available for gsi::Expressions.
|
|
*/
|
|
void set_gsi_data (PerClassClientSpecificData *data) const
|
|
{
|
|
set_data (ClientIndex::Basic, data);
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the per-client data for gsi::Expressions
|
|
*/
|
|
PerClassClientSpecificData *gsi_data () const
|
|
{
|
|
return data (ClientIndex::Basic);
|
|
}
|
|
|
|
protected:
|
|
static const class_collection &collection ();
|
|
|
|
const tl::weak_collection<ClassBase> &subclasses () const
|
|
{
|
|
return m_subclasses;
|
|
}
|
|
|
|
void set_name (const std::string &n)
|
|
{
|
|
m_name = n;
|
|
}
|
|
|
|
void set_parent (const ClassBase *parent);
|
|
void set_base (const ClassBase *base);
|
|
|
|
private:
|
|
const ClassBase *mp_base, *mp_parent;
|
|
std::string m_doc;
|
|
Methods m_methods;
|
|
std::vector<MethodBase *> m_callbacks, m_constructors;
|
|
std::string m_name;
|
|
tl::weak_collection<ClassBase> m_child_classes, m_subclasses;
|
|
mutable std::auto_ptr<PerClassClientSpecificData> mp_data[ClientIndex::MaxClientIndex];
|
|
|
|
static class_collection *mp_class_collection;
|
|
static unsigned int m_class_count;
|
|
|
|
// No copying
|
|
ClassBase (const ClassBase &other);
|
|
ClassBase &operator= (const ClassBase &other);
|
|
};
|
|
|
|
/**
|
|
* @brief Accessor to a declaration through name
|
|
*/
|
|
GSI_PUBLIC const ClassBase *class_by_name (const std::string &name);
|
|
|
|
/**
|
|
* @brief Returns true if there is a class with the given name
|
|
*/
|
|
GSI_PUBLIC bool has_class (const std::string &name);
|
|
|
|
/**
|
|
* @brief Find a class declaration through the type info
|
|
*/
|
|
GSI_PUBLIC const ClassBase *class_by_typeinfo (const std::type_info &ti);
|
|
|
|
/**
|
|
* @brief Returns true if there is a class with the given type info
|
|
*/
|
|
GSI_PUBLIC bool has_class (const std::type_info &ti);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|