klayout/src/db/db/dbCell.h

1041 lines
32 KiB
C++

/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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_dbCell
#define HDR_dbCell
#include "dbCommon.h"
#include "dbInstances.h"
#include "dbObject.h"
#include "dbMemStatistics.h"
#include "dbBox.h"
#include "dbBoxTree.h"
#include "dbBoxConvert.h"
#include "dbShape.h"
#include "dbShapes.h"
#include "dbCellInst.h"
#include "dbArray.h"
#include "tlTypeTraits.h"
#include "tlVector.h"
#include "tlAlgorithm.h"
#include "gsi.h"
#include <map>
#include <set>
namespace db
{
template <class C> class cell_list;
template <class C> class cell_list_const_iterator;
template <class C> class cell_list_iterator;
template <class Coord> class generic_repository;
class Layout;
class Library;
class ImportLayerMapping;
/**
* @brief The cell object
*
* A cell object consists of a set of shape containers (called layers),
* a set of child cell instances and auxiliary informations such as
* the parent instance list.
* A cell is identified through an index given to the cell upon instantiation.
* The cell index is valid in the context of a cell graph object which
* must issue the cell index.
*/
class DB_PUBLIC Cell
: public db::Object,
public gsi::ObjectBase
{
public:
typedef db::Box box_type;
typedef std::map<unsigned int, box_type> box_map;
typedef box_type::coord_type coord_type;
typedef db::CellInst cell_inst_type;
typedef db::simple_trans<coord_type> array_trans;
typedef db::array<cell_inst_type, array_trans> cell_inst_array_type;
typedef db::Shapes shapes_type;
typedef db::Shapes::shape_iterator shape_iterator;
typedef std::map<unsigned int, shapes_type> shapes_map;
typedef db::Instances instances_type;
typedef db::Instance instance_type;
typedef instances_type::touching_iterator touching_iterator;
typedef instances_type::overlapping_iterator overlapping_iterator;
typedef instances_type::const_iterator const_iterator;
typedef instances_type::parent_inst_type parent_inst_type;
typedef instances_type::parent_inst_iterator parent_inst_iterator;
typedef instances_type::parent_cell_iterator parent_cell_iterator;
typedef instances_type::child_cell_iterator child_cell_iterator;
typedef instances_type::basic_inst_type basic_inst_type;
typedef instances_type::sorted_inst_iterator sorted_inst_iterator;
friend class db::Layout;
friend class db::Library;
friend class db::cell_list<Cell>;
friend class db::cell_list_iterator<Cell>;
friend class db::cell_list_const_iterator<Cell>;
friend class db::Instances;
/**
* @brief The destructor
*/
virtual ~Cell ();
/**
* @brief The assignment operator
*
* The assignment operator does not change the association of the cell
* with a layout. It copies the "content" of the cell, where the instances
* refer to the same cell index than in the source cell.
*
* HINT: this implementation can copy cell contents from one layout to
* another. However, currently property id are not translated which limits
* the use of this method in this case to 1-to-1 copies of layouts.
*/
Cell &operator= (const Cell &d);
/**
* @brief Returns the number of layers stored in that cell
*/
unsigned int layers () const;
/**
* @brief Return the const shapes list of the given layer
*
* This method allows to access the shapes list on a certain layer.
* If the layer does not exist yet, a reference to an empty list is
* returned.
*
* @param index The layer index of the shapes list to retrieve
*
* @return A const reference to the shapes list
*/
shapes_type &shapes (unsigned int index);
/**
* @brief Return the shapes list of the given layer
*
* This method allows to access the shapes list on a certain layer.
* If the layer does not exist yet, it is created.
*
* @param index The layer index of the shapes list to retrieve
*
* @return A reference to the shapes list
*/
const shapes_type &shapes (unsigned int index) const;
/**
* @brief Gets the index of a given shapes array
*
* If the shapes container is not part of the cell, std::numeric_limits<unsigned int>::max ()
* is returned.
*
* This is not a cheap operation.
*/
unsigned int index_of_shapes (const shapes_type *shapes) const;
/**
* @brief Clear all shapes in the cell
*/
void clear_shapes ();
/**
* @brief Clear the instance list
*/
void clear_insts ()
{
if (! m_instances.empty ()) {
m_instances.clear_insts ();
}
}
/**
* @brief Copy the shapes from layer src to dest
*
* The target layer is not overwritten. Instead, the shapes are added to the target layer's shapes.
*/
void copy (unsigned int src, unsigned int dest);
/**
* @brief Move the shapes from layer src to dest
*
* The target layer is not overwritten. Instead, the shapes are added to the target layer's shapes.
*/
void move (unsigned int src, unsigned int dest);
/**
* @brief Swap the layers given
*/
void swap (unsigned int i1, unsigned int i2);
/**
* @brief Clear the shapes on the given layer
*/
void clear (unsigned int index);
/**
* @brief Erase a cell instance given by a instance proxy
*
* Erasing a cell instance will destroy the sorting order and invalidate
* other instance proxies.
* sort() must be called before a region query can be done
* on the cell instances.
*/
void erase (const instance_type &ref)
{
m_instances.erase (ref);
}
/**
* @brief Erase a cell instance
*
* Erasing a cell instance will destroy the sorting order.
* sort() must be called before a region query can be done
* on the cell instances. update_bbox() must be called
* explicitly before the bounding box can be updated.
*/
void erase (const_iterator e)
{
m_instances.erase (e);
}
/**
* @brief Erasing of multiple instances
*
* Erase a set of positions given by an iterator I: *(from,to).
* *I must render an "iterator" object.
* The iterators in the sequence from, to must be sorted in
* "operator<" order.
*
* @param first The start of the sequence of iterators
* @param last The end of the sequence of iterators
*/
void erase_insts (const std::vector<instance_type> &instances)
{
m_instances.erase_insts (instances);
}
/**
* @brief Insert a generic cell instance
*
* Inserting a cell instance will destroy the sorting order.
* sort() must be called before a region query can be done
* on the cell instances. update_bbox() must be called
* explicitly before the bounding box can be updated.
*/
template <class Inst>
Instance insert (const Inst &inst)
{
return m_instances.insert (inst);
}
/**
* @brief Insert a sequence [from,to) of cell instances
*
* @param from The start of the sequence
* @param to The past-the-end pointer of the sequence
*/
template <class I>
void insert (I from, I to)
{
m_instances.insert (from, to);
}
/**
* @brief Insert an instance given by a instance reference
*
* This member may be used to copy an instance from one cell to another.
* Because of the inherent instability of the instance pointer it must not be
* used to copy instances within one cell.
*
* @param instance The instance reference of which to insert a copy
*/
instance_type insert (const instance_type &instance)
{
return (m_instances.insert (instance));
}
/**
* @brief Transform the instance pointed to by the instance reference
*
* @param t The transformation to apply
*/
template <class Trans>
instance_type transform (const instance_type &ref, const Trans &t)
{
return m_instances.transform (ref, t);
}
/**
* @brief Transform the instance pointed to by the instance reference into a new coordinate system
*
* @param t The transformation to apply
*/
template <class Trans>
instance_type transform_into (const instance_type &ref, const Trans &t)
{
return m_instances.transform_into (ref, t);
}
/**
* @brief Transforms the cell into a new coordinate system.
*
* The transformation is not applied to the children, but this method enables propagation
* because the transformation is only applied to the instances insofar that it can be
* applied to the children as well.
*
* @param t The transformation to apply
*/
template <class Trans>
void transform_into (const Trans &t)
{
m_instances.transform_into (t);
for (typename shapes_map::iterator s = m_shapes_map.begin (); s != m_shapes_map.end (); ++s) {
if (! s->second.empty ()) {
// Note: don't use the copy ctor here - it will copy the attachment to the manager
// and create problems when destroyed. Plus: swap would be more efficient. But by using
// assign_transformed we get undo support for free.
shapes_type d;
d = s->second;
s->second.assign_transformed (d, t);
}
}
}
/**
* @brief Insert an instance given by a instance reference with a different cell index and property ID
*
* This member may be used to map an instance to another layout object.
*
* @param ref The instance reference of which to insert a copy
* @param im The mapper to new cell index to use (for mapping to a different layout for example)
* @param pm The mapper to new cell property ID use (for mapping to a different layout for example)
*/
template <class IndexMap, class PropIdMap>
instance_type insert (const instance_type &ref, IndexMap &im, PropIdMap &pm)
{
return (m_instances.insert (ref, im, pm));
}
/**
* @brief Test if the given reference is valid
*
* Returns true, if the given instance is valid. It is not valid, if it has been
* deleted already. However, it may happen, that the instance memory has been
* reused already. Therefore this method can safely be used only if nothing
* has been inserted into this container in between.
* This method can only be used in editable mode.
*
* @param instance The reference to the instance
*/
bool is_valid (const instance_type &ref) const
{
return m_instances.is_valid (ref);
}
/**
* @brief Replace the properties ID of an element (pointed to by the iterator) with the given one
*
* The iterator must point to a instance already having a property ID.
* If this is not the case, an exception is thrown
*/
instance_type replace_prop_id (const instance_type &ref, db::properties_id_type prop_id)
{
return m_instances.replace_prop_id (ref, prop_id);
}
/**
* @brief Replace the instance pointed to by the iterator with the given instance
*
* This method will delete the former object if it is not of the correct kind - i.e. it will
* delete an object without a property and insert a new one with a property.
* This may invalidate other references in non-editable mode.
* If the inserted instance is one without a property and the existing instance has a property,
* the latter is not touched.
*/
template <class InstArray>
instance_type replace (const instance_type &ref, const InstArray &inst)
{
return m_instances.replace (ref, inst);
}
/**
* @brief Test, if the given instance is a PCell instance
*
* The return value is a pair of a boolean which is true when the instance is a PCell
* instance and the PCell id of the instance if this is the case.
*
* @param ref The instance to test
* @return See above
*/
std::pair<bool, db::pcell_id_type> is_pcell_instance (const instance_type &ref) const;
/**
* @brief Gets the PCell parameters of a PCell instance
*
* For the order of the parameters, ask the PCell declaration (available trough Layout::pcell_declaration
* from the PCell id.
*
* @return A list of parameters in the order they are declared.
*/
const std::vector<tl::Variant> &get_pcell_parameters (const instance_type &ref) const;
/**
* @brief Gets a PCell parameter of a PCell instance
*
* @return The value of the PCell parameter with the given name or a nil variant if there is no such parameter
*/
tl::Variant get_pcell_parameter (const instance_type &ref, const std::string &name) const;
/**
* @brief Gets the PCell parameters of a PCell instance as a name to value map
*
* @return The PCell parameter values by name
*/
std::map<std::string, tl::Variant> get_named_pcell_parameters (const instance_type &ref) const;
/**
* @brief Changes the PCell parameters of a PCell instance
*
* For the order of the parameters, ask the PCell declaration (available trough Layout::pcell_declaration
* from the PCell id.
* This method is only allowed in editable mode.
*
* @return A reference to the new instance. The original reference may be invalid.
*/
instance_type change_pcell_parameters (const instance_type &ref, const std::vector<tl::Variant> &new_parameters);
/**
* @brief The cell index accessor method
*
* @return The cell index of the cell
*/
const cell_index_type &cell_index () const
{
return m_cell_index;
}
/**
* @brief Update the child-parent relationships
*
* This will update the child-parent relationships. Basically
* this means entering the cell as a parent into all it's child
* cells.
*/
void update_relations ();
/**
* @brief Check if the bbox needs update because the shapes have changed
*
* Returns true if the bounding box needs update because the
* shape bounding box (not one of the child bounding boxes) has changed.
*/
bool is_shape_bbox_dirty () const;
/**
* @brief Update the bbox
*
* This will update the bbox from the shapes and instances.
* This requires the bboxes of the child cells to be computed
* before. Practically this will be done by computing the
* bboxes bottom-up in the hierarchy.
* In addition, the number of hierarchy leves below is also
* updated.
*
* @param layers The max. number of layers in the child cells
* @return true, if the bounding box has changed.
*/
bool update_bbox (unsigned int layers);
/**
* @brief Sort the shapes lists
*
* This will sort the shapes lists for query of regions
* on a per-shape basis. Since sorting of the shapes is
* guarded against redundant sorting (db::Layer::sort),
* we can safely call the sort method in any case.
*/
void sort_shapes ();
/**
* @brief Retrieve the bounding box of the cell
*
* Before the bounding box can be retrieved, it must have
* been computed using update_bbox. This is performed by
* requesting an update from the graph.
*
* @return The bounding box that was computed by update_bbox
*/
const box_type &bbox () const;
/**
* @brief Retrieve the per-layer bounding box of the cell
*
* Before the bounding box can be retrieved, it must have
* been computed using update_bbox. This is performed by
* requesting an update from the graph.
*
* @return The bounding box that was computed by update_bbox
*/
const box_type &bbox (unsigned int l) const;
/**
* @brief Region query for the instances in "overlapping" mode
*
* This will return the region query iterator for the child cell
* instances overlapping with the given region b.
*
* @param b The region to query
*
* @return The region iterator for the child cell instances
*/
overlapping_iterator begin_overlapping (const box_type &b) const;
/**
* @brief Region query for the instances in "touching" mode
*
* This will return the region query iterator for the child cell
* instances touching the given region b.
*
* @param b The region to query
*
* @return The region iterator for the child cell instances
*/
touching_iterator begin_touching (const box_type &b) const;
/**
* @brief The child cell iterator
*
* This iterator will report the child cell indices, not every instance.
* Basically this is a filter which makes it slow.
*/
child_cell_iterator begin_child_cells () const;
/**
* @brief Report the number of child cells
*
* Just the number of child cells with distinct cell indices are
* reported.
* CAUTION: this method is SLOW!
*/
size_t child_cells () const;
/**
* @brief The number of cell instances
*/
size_t cell_instances () const
{
return m_instances.cell_instances ();
}
/**
* @brief The cell instance access begin iterator
*
* The iterator follows the "at_end" semantics.
*/
const_iterator begin () const;
/**
* @brief The cell instance access by index in list of sorted instances
*
* The iterator returned will point to the i-th element, where i is the index in the list
* of instances sorted by cell index.
* The iterator follows the "at_end" semantics.
*/
instance_type sorted_inst_ptr (size_t i) const
{
return m_instances.instance_from_pointer (m_instances.begin_sorted_insts () [i]);
}
/**
* @brief The cell instance access by index in list of sorted instances
*
* The pointer returned will point to the i-th element, where i is the index in the list
* of instances sorted by cell index. This is just a "basic_inst_type" pointer without any further
* hint about what object is being hidden behind it.
*/
const basic_inst_type *basic_sorted_inst_ptr (size_t i) const
{
return m_instances.begin_sorted_insts () [i];
}
/**
* @brief The iterator for the instance list sorted by cell index
*/
const sorted_inst_iterator begin_sorted_insts () const
{
return m_instances.begin_sorted_insts ();
}
/**
* @brief The end iterator for the instance list sorted by cell index
*/
const sorted_inst_iterator end_sorted_insts () const
{
return m_instances.end_sorted_insts ();
}
/**
* @brief The parent instance list begin iterator
*
* The begin_parent_insts() allows to access to the parent instance list.
*/
parent_inst_iterator begin_parent_insts () const;
/**
* @brief Report the number of parent cells
*
* Since the m_parent_insts vector just stores references to those cells
* that have distinct cell indices, we can simply report their length.
*/
size_t parent_cells () const;
/**
* @brief The parent cell iterator
*
* This iterator will iterate over the parent cells, just returning their
* cell index.
*/
parent_cell_iterator begin_parent_cells () const;
/**
* @brief The parent cell end iterator
*/
parent_cell_iterator end_parent_cells () const;
/**
* @brief Tell if the cell is a top-level cell
*
* A cell is a top-level cell if there are no parent instantiations.
*/
bool is_top () const;
/**
* @brief Tell if the cell is a leaf cell
*
* A cell is a leaf cell if there are no child instantiations.
*/
bool is_leaf () const;
/**
* @brief Return the number of hierarchy levels below (expensive)
*/
unsigned int hierarchy_levels () const;
/**
* @brief begin iterator of all shapes
*
* @param layer The layer from which to query the shapes
* @param flags The flags of shapes to query (see db::shape documentation)
* @param prop_sel A property selector (a set of property set ids)
* @param inv_prop_sel true, if prop_sel should select all ids that should not be iterated
*
* @return The iterator delivering all these shapes
*/
shape_iterator begin (unsigned int layer, unsigned int flags, const shape_iterator::property_selector *prop_sel = 0, bool inv_prop_sel = false) const
{
return shapes (layer).begin (flags, prop_sel, inv_prop_sel);
}
/**
* @brief begin iterator of all shapes with a overlapping mode region query
*
* @param box The region to query the shapes from
* @param layer The layer from which to query the shapes
* @param flags The flags of shapes to query (see db::shape documentation)
* @param prop_sel A property selector (a set of property set ids)
* @param inv_prop_sel true, if prop_sel should select all ids that should not be iterated
*
* @return The iterator delivering all these shapes
*/
shape_iterator begin_overlapping (unsigned int layer, const box_type &box, unsigned int flags, const shape_iterator::property_selector *prop_sel = 0, bool inv_prop_sel = false) const
{
return shapes (layer).begin_overlapping (box, flags, prop_sel, inv_prop_sel);
}
/**
* @brief begin iterator of all shapes with a touching mode region query
*
* This method ensures that the box tress are updated before the query is done.
* The db::Shape-specific iterator does not do that.
*
* @param box The region to query the shapes from
* @param layer The layer from which to query the shapes
* @param flags The flags of shapes to query (see db::shape documentation)
* @param prop_sel A property selector (a set of property set ids)
* @param inv_prop_sel true, if prop_sel should select all ids that should not be iterated
*
* @return The iterator delivering all these shapes
*/
shape_iterator begin_touching (unsigned int layer, const box_type &box, unsigned int flags, const shape_iterator::property_selector *prop_sel = 0, bool inv_prop_sel = false) const
{
return shapes (layer).begin_touching (box, flags, prop_sel, inv_prop_sel);
}
/**
* @brief Collect all calling cells (either calling this cell directly or indirectly)
*
* This method adds all cell indices of all cells that either directly or indirectly
* call this cell to the set given. It is assumed that the if the set contains a cell, it
* will also contain all called cells, so it may act as a cache.
*
* @param callers The set of called cells (used as cache)
*/
void collect_caller_cells (std::set<cell_index_type> &callers) const;
/**
* @brief Collect all calling cells (either calling this cell directly or indirectly) up to a certain level of hierarchy
*
* This method adds all cell indices of all cells that either directly or indirectly
* call this cell to the set given. It is assumed that the if the set contains a cell, it
* will also contain all called cells, so it may act as a cache.
*
* @param callers The set of called cells (used as cache)
* @param levels The number of levels to descend (0: none, 1: direct callers ...)
*/
void collect_caller_cells (std::set<cell_index_type> &callers, int levels) const;
/**
* @brief Collect all calling cells (either calling this cell directly or indirectly) up to a certain level of hierarchy
*
* This method adds all cell indices of all cells that either directly or indirectly
* call this cell to the set given. It is assumed that the if the set contains a cell, it
* will also contain all called cells, so it may act as a cache.
*
* This version allows to restrict the search to a cone of the hierarchy tree, that is
* a set of cells which are collected from another call of "collect_called_cells" with another initial cell.
*
* @param callers The set of called cells (used as cache)
* @param cone The selection cone
* @param levels The number of levels to descend (0: none, 1: direct callers ..., -1: all)
*/
void collect_caller_cells (std::set<cell_index_type> &callers, const std::set<cell_index_type> &cone, int levels) const;
/**
* @brief Collect all cells called either directly or indirectly by this cell
*
* This method adds all cell indices of all cells called either directly or indirectly
* by this cell to the set given. It is assumed that the if the set contains a cell, it
* will also contain all called cells, so it may act as a cache.
*
* @param called The set of called cells (used as cache)
*/
void collect_called_cells (std::set<cell_index_type> &called) const;
/**
* @brief Collect all cells called either directly or indirectly by this cell down to a certain level of hierarchy
*
* This method adds all cell indices of all cells called either directly or indirectly
* by this cell to the set given. It is assumed that the if the set contains a cell, it
* will also contain all called cells, so it may act as a cache.
*
* @param called The set of called cells (used as cache)
* @param levels The number of levels to descend (0: none, 1: direct callers ...)
*/
void collect_called_cells (std::set<cell_index_type> &called, int level) const;
/**
* @brief Unregister a cell inside it's context.
*
* This method is called when a cell es taken out of a layout.
* It can for example, unregister a PCell variant from a PCell header.
*/
virtual void unregister () { }
/**
* @brief Reregister a cell from it's context.
*
* This method is called when a cell es inserted again into a layout.
* It can for example, register a PCell variant at a PCell header.
*/
virtual void reregister () { }
/**
* @brief Update the layout
*
* This method does not have any effect except for derived classes where it updates the layout
* with the current state, i.e. if a PCell declaration has changed.
*/
virtual void update (ImportLayerMapping * /*layer_mapping*/ = 0) { }
/**
* @brief Tell, if this cell is a proxy cell
*
* Proxy cells are such whose layout represents a snapshot of another entity.
* Such cells can be PCell variants or library references for example.
*/
virtual bool is_proxy () const
{
return false;
}
/**
* @brief Sets the cell name
*
* If a cell with that name already exists, a new name is created by appending a suffix.
*/
void set_name (const std::string &name);
/**
* @brief Get the basic name
*
* The basic name of the cell is either the cell name or the cell name in the
* target library (for library proxies) or the PCell name (for PCell proxies).
* The actual name may be different by a extension to make it unique.
*/
virtual std::string get_basic_name () const;
/**
* @brief Gets the display name
*
* The display name is some "nice" descriptive name of the cell (variant)
* For normal cells this name is equivalent to the normal cell name.
*
* PCells will indicate the parameters in the display name. Library cells
* will indicate the library name the same way than the qualified name does.
* Ghost cells will be indicated by enclosing the name in brackets.
*/
virtual std::string get_display_name () const;
/**
* @brief Gets the qualified name
*
* The qualified name contains a reference to the library, if the cell
* is a library reference. Otherwise it is identical to the basic name.
*/
virtual std::string get_qualified_name () const;
/**
* @brief Returns a value indicating whether the cell is a "ghost cell"
*
* The ghost cell flag is used by the GDS reader for example to indicate that
* the cell is not located inside the file. Upon writing the reader can determine
* whether to write the cell or not.
* To satisfy the references inside the layout, a dummy cell is created in this case
* which has the "ghost cell" flag set to true.
*/
bool is_ghost_cell () const
{
return m_ghost_cell;
}
/**
* @brief Sets the "ghost cell" flag
*
* See "is_ghost_cell" for a description of this property.
*/
void set_ghost_cell (bool g)
{
m_ghost_cell = g;
}
/**
* @brief Returns a value indicating whether the cell is empty
*
* An empty cell is a cell not containing instances nor shapes.
*/
bool empty () const;
/**
* @brief Invalidate the instances bounding box (to be called by the instances container)
*/
void invalidate_insts ();
/**
* @brief Invalidate the hierarchical structure (to be called by the instances container)
*/
void invalidate_hier ();
/**
* @brief Implementation of the redo method
*/
void redo (db::Op *op);
/**
* @brief Implementation of the undo method
*/
void undo (db::Op *op);
/**
* @brief Collect memory usage statistics
*/
virtual void collect_mem_stat (db::MemStatistics &m) const;
/**
* @brief Sets the properties ID
*/
void prop_id (db::properties_id_type id);
/**
* @brief Gets the properties ID
*/
db::properties_id_type prop_id () const
{
return m_prop_id;
}
/**
* @brief Get a reference to the layout object
*/
db::Layout *layout ()
{
return mp_layout;
}
/**
* @brief Get a reference to the layout object (const version)
*/
const db::Layout *layout () const
{
return mp_layout;
}
protected:
/**
* @brief Standard constructor: create an empty cell object
*
* Takes the manager object from the graph object.
*
* @param ci The index of the cell
* @param g A reference to the graph object that owns the cell
*/
Cell (cell_index_type ci, db::Layout &g);
/**
* @brief Copy constructor
*
* The copy constructor copies the contents of the cell and
* associates the new cell with the same layout than the source cell.
*/
Cell (const Cell &d);
/**
* @brief Clone the cell and attach to a different layout
*/
virtual Cell *clone (db::Layout &layout) const;
private:
cell_index_type m_cell_index;
mutable db::Layout *mp_layout;
shapes_map m_shapes_map;
instances_type m_instances;
box_type m_bbox;
box_map m_bboxes;
db::properties_id_type m_prop_id;
// packed fields
unsigned int m_hier_levels : 29;
bool m_bbox_needs_update : 1;
bool m_ghost_cell : 1;
static box_type ms_empty_box;
// linked list, used by Layout
Cell *mp_last, *mp_next;
// clear the shapes without telling the graph
void clear_shapes_no_invalidate ();
// helper function for computing the number of hierarchy levels
// must be called bottom-up
unsigned int count_hier_levels () const;
/**
* @brief Set the cell index
*/
void set_cell_index (db::cell_index_type ci)
{
m_cell_index = ci;
}
/**
* @brief Return a reference to the instances object
*/
instances_type &instances ()
{
return m_instances;
}
/**
* @brief Return a reference to the instances object
*/
const instances_type &instances () const
{
return m_instances;
}
/**
* @brief Count the number of parent instances
*
* This will accumulate the number of parent instances in the vector
* provided. Later, this count is used to resize the parent instance
* vector.
*/
void count_parent_insts (std::vector <size_t> &count) const;
/**
* @brief Clear the parent instance list
*
* Reserve the given number of entries.
*/
void clear_parent_insts (size_t sz = 0);
/**
* @brief Sort the child instance list
*
* The child instances are first sorted by cell index, then by raw transformation
* (excluding displacement). This allows to simplify the bbox computation by
* convolution of the displacements bboxes with the object bboxes.
*/
void sort_child_insts ();
/**
* @brief Sort the cell instance list
*
* This will sort the cell instance list. As a prerequesite
* the cell's bounding boxes must have been computed.
*
* @param layers The maximum number of layers in the child cells
*/
void sort_inst_tree ();
};
} // namespace db
namespace tl
{
/**
* @brief Type traits
*/
template <> struct type_traits <db::Cell> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_default_constructor;
};
}
#endif