WIP: refactoring, unify shape iterator

This commit is contained in:
Matthias Koefferlein 2020-09-26 23:41:39 +02:00
parent f05fd28a94
commit 26028cdeb9
13 changed files with 522 additions and 411 deletions

View File

@ -28,6 +28,7 @@ SOURCES = \
dbEdges.cc \
dbFillTool.cc \
dbFuzzyCellMapping.cc \
dbGenericShapeIterator.cc \
dbGlyphs.cc \
dbHershey.cc \
dbInstances.cc \
@ -63,6 +64,7 @@ SOURCES = \
dbRegionLocalOperations.cc \
dbSaveLayoutOptions.cc \
dbShape.cc \
dbShapeFlags.cc \
dbShapes2.cc \
dbShapes3.cc \
dbShapes.cc \
@ -224,6 +226,7 @@ HEADERS = \
dbEdgesToContours.h \
dbFillTool.h \
dbFuzzyCellMapping.h \
dbGenericShapeIterator.h \
dbHash.h \
dbHersheyFont.h \
dbHershey.h \
@ -263,6 +266,7 @@ HEADERS = \
dbRegionLocalOperations.h \
dbSaveLayoutOptions.h \
dbShape.h \
dbShapeFlags.h \
dbShapeRepository.h \
dbShapes2.h \
dbShapeProcessor.h \

View File

@ -79,11 +79,28 @@ public:
return &m_polygon;
}
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
{
const DeepRegionIterator *o = dynamic_cast<const DeepRegionIterator *> (other);
return o && o->m_iter == m_iter;
}
virtual RegionIteratorDelegate *clone () const
{
return new DeepRegionIterator (*this);
}
virtual void do_reset (const db::Box &region, bool overlapping)
{
m_iter.set_region (region);
m_iter.set_overlapping (overlapping);
}
virtual db::Box bbox () const
{
return m_iter.bbox ();
}
private:
friend class Region;

View File

@ -142,7 +142,7 @@ FlatRegion::ensure_merged_polygons_valid () const
RegionIteratorDelegate *FlatRegion::begin () const
{
return new FlatRegionIterator (m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (), m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end ());
return new FlatRegionIterator (&m_polygons);
}
RegionIteratorDelegate *FlatRegion::begin_merged () const
@ -151,7 +151,7 @@ RegionIteratorDelegate *FlatRegion::begin_merged () const
return begin ();
} else {
ensure_merged_polygons_valid ();
return new FlatRegionIterator (m_merged_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (), m_merged_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end ());
return new FlatRegionIterator (&m_merged_polygons);
}
}

View File

@ -35,44 +35,7 @@ namespace db {
/**
* @brief An iterator delegate for the flat region
*/
class DB_PUBLIC FlatRegionIterator
: public RegionIteratorDelegate
{
public:
typedef db::layer<db::Polygon, db::unstable_layer_tag> polygon_layer_type;
typedef polygon_layer_type::iterator iterator_type;
FlatRegionIterator (iterator_type from, iterator_type to)
: m_from (from), m_to (to)
{
// .. nothing yet ..
}
virtual bool at_end () const
{
return m_from == m_to;
}
virtual void increment ()
{
++m_from;
}
virtual const value_type *get () const
{
return m_from.operator-> ();
}
virtual RegionIteratorDelegate *clone () const
{
return new FlatRegionIterator (*this);
}
private:
friend class Region;
iterator_type m_from, m_to;
};
typedef generic_shapes_iterator_delegate<db::Polygon> FlatRegionIterator;
/**
* @brief A flat, polygon-set delegate

View File

@ -0,0 +1,23 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 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
*/
#include "dbGenericShapeIterator.h"

View File

@ -0,0 +1,322 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 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_dbGenericShapeIterator
#define HDR_dbGenericShapeIterator
#include "dbCommon.h"
#include "dbShapes.h"
#include "dbShapeFlags.h"
namespace db
{
template <class T>
class DB_PUBLIC generic_shape_iterator_delegate_base
{
public:
typedef T value_type;
generic_shape_iterator_delegate_base () { }
virtual ~generic_shape_iterator_delegate_base () { }
virtual void do_reset (const db::Box & /*region*/, bool /*overlapping*/) { }
virtual db::Box bbox () const { return db::Box::world (); }
virtual bool at_end () const = 0;
virtual void increment () = 0;
virtual const T *get () const = 0;
virtual generic_shape_iterator_delegate_base<T> *clone () const = 0;
virtual bool equals (const generic_shape_iterator_delegate_base<T> *other) const = 0;
};
template <class Iter>
class DB_PUBLIC generic_shape_iterator_delegate2
: public generic_shape_iterator_delegate_base<typename Iter::value_type>
{
public:
typedef typename Iter::value_type value_type;
generic_shape_iterator_delegate2 (const Iter &from, const Iter &to)
: m_iter (from), m_from (from), m_to (to)
{ }
virtual void do_reset (const db::Box &, bool)
{
m_iter = m_from;
}
virtual bool at_end () const
{
return m_iter == m_to;
}
virtual void increment ()
{
++m_iter;
}
virtual const value_type *get () const
{
return m_iter.operator-> ();
}
generic_shape_iterator_delegate_base<value_type> *clone () const
{
return new generic_shape_iterator_delegate2<Iter> (*this);
}
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
{
const generic_shape_iterator_delegate2<Iter> *o = dynamic_cast<const generic_shape_iterator_delegate2<Iter> *> (other);
return o && o->m_iter == m_iter;
}
private:
Iter m_iter, m_from, m_to;
};
template <class Iter>
class DB_PUBLIC generic_shape_iterator_delegate1
: public generic_shape_iterator_delegate_base<typename Iter::value_type>
{
public:
typedef typename Iter::value_type value_type;
generic_shape_iterator_delegate1 (const Iter &from)
: m_iter (from), m_from (from)
{ }
virtual void do_reset (const db::Box &, bool)
{
m_iter = m_from;
}
virtual bool at_end () const
{
return m_iter.at_end ();
}
virtual void increment ()
{
++m_iter;
}
virtual const value_type *get () const
{
return m_iter.operator-> ();
}
generic_shape_iterator_delegate_base<value_type> *clone () const
{
return new generic_shape_iterator_delegate1<Iter> (*this);
}
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
{
const generic_shape_iterator_delegate1<Iter> *o = dynamic_cast<const generic_shape_iterator_delegate1<Iter> *> (other);
return o && o->m_iter == m_iter;
}
private:
Iter m_iter, m_from;
};
template <class T>
class DB_PUBLIC generic_shapes_iterator_delegate
: public generic_shape_iterator_delegate_base<T>
{
public:
generic_shapes_iterator_delegate (const db::Shapes *shapes)
: mp_shapes (shapes), m_iter (mp_shapes->begin (shape_flags<T> ()))
{
// .. nothing yet ..
}
virtual void do_reset (const db::Box &box, bool overlapping)
{
if (box == db::Box::world ()) {
m_iter = mp_shapes->begin (shape_flags<T> ());
} else {
if (mp_shapes->is_bbox_dirty ()) {
const_cast<db::Shapes *> (mp_shapes)->update ();
}
if (overlapping) {
m_iter = mp_shapes->begin_overlapping (box, shape_flags<T> ());
} else {
m_iter = mp_shapes->begin_touching (box, shape_flags<T> ());
}
}
}
virtual bool at_end () const
{
return m_iter.at_end ();
}
virtual void increment ()
{
++m_iter;
}
virtual const T *get () const
{
return m_iter->basic_ptr (typename T::tag ());
}
generic_shape_iterator_delegate_base<T> *clone () const
{
return new generic_shapes_iterator_delegate<T> (*this);
}
virtual db::Box bbox () const
{
if (mp_shapes->is_bbox_dirty ()) {
const_cast<db::Shapes *> (mp_shapes)->update ();
}
return mp_shapes->bbox ();
}
virtual bool equals (const generic_shape_iterator_delegate_base<T> *other) const
{
const generic_shapes_iterator_delegate<T> *o = dynamic_cast<const generic_shapes_iterator_delegate<T> *> (other);
return o && o->mp_shapes == mp_shapes && o->m_iter.at_end () == m_iter.at_end () && (m_iter.at_end () || o->m_iter->basic_ptr (typename T::tag ()) == m_iter->basic_ptr (typename T::tag ()));
}
private:
const db::Shapes *mp_shapes;
db::Shapes::shape_iterator m_iter;
generic_shapes_iterator_delegate (const generic_shapes_iterator_delegate &other)
: mp_shapes (other.mp_shapes), m_iter (other.m_iter)
{
// .. nothing yet ..
}
};
template <class T>
class DB_PUBLIC generic_shape_iterator
{
public:
typedef T value_type;
typedef const value_type &reference;
typedef const value_type *pointer;
typedef std::forward_iterator_tag iterator_category;
typedef void difference_type;
template <class Iter>
generic_shape_iterator (const Iter &from, const Iter &to)
: mp_delegate (new generic_shape_iterator_delegate2<Iter> (from, to))
{ }
template <class Iter>
generic_shape_iterator (const Iter &from)
: mp_delegate (new generic_shape_iterator_delegate1<Iter> (from))
{ }
generic_shape_iterator ()
: mp_delegate (0)
{ }
generic_shape_iterator (generic_shape_iterator_delegate_base<T> *delegate)
: mp_delegate (delegate)
{ }
generic_shape_iterator (const db::Shapes *shapes)
: mp_delegate (new generic_shapes_iterator_delegate<T> (shapes))
{ }
generic_shape_iterator (const generic_shape_iterator &other)
: mp_delegate (other.mp_delegate ? other.mp_delegate->clone () : 0)
{ }
~generic_shape_iterator ()
{
delete mp_delegate;
}
generic_shape_iterator &operator= (const generic_shape_iterator &other)
{
if (this != &other) {
delete mp_delegate;
mp_delegate = other.mp_delegate ? other.mp_delegate->clone () : 0;
}
return *this;
}
bool operator== (const generic_shape_iterator<T> &other) const
{
return mp_delegate && other.mp_delegate && mp_delegate->equals (other.mp_delegate);
}
template <class TO>
bool operator== (const generic_shape_iterator<TO> &) const
{
return false;
}
reference operator* () const
{
return *mp_delegate->get ();
}
pointer operator-> () const
{
return mp_delegate->get ();
}
generic_shape_iterator &operator++ ()
{
mp_delegate->increment ();
return *this;
}
bool at_end () const
{
return !mp_delegate || mp_delegate->at_end ();
}
void reset ()
{
if (mp_delegate) {
mp_delegate->do_reset (db::Box::world (), false);
}
}
void reset (const db::Box &box, bool overlapping)
{
if (mp_delegate) {
mp_delegate->do_reset (box, overlapping);
}
}
db::Box bbox () const
{
return mp_delegate ? mp_delegate->bbox () : db::Box ();
}
public:
generic_shape_iterator_delegate_base<T> *mp_delegate;
};
}
#endif

View File

@ -28,6 +28,7 @@
#include "dbEdgeProcessor.h"
#include "dbPolygonGenerators.h"
#include "dbLocalOperationUtils.h"
#include "dbShapeFlags.h"
#include "tlLog.h"
#include "tlTimer.h"
#include "tlInternational.h"
@ -1637,7 +1638,7 @@ struct scan_shape2shape_same_layer
}
void
operator () (const shapes_iterator<TS> &, unsigned int, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
operator () (const generic_shape_iterator<TS> &, unsigned int, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
{
// cannot have different types on the same layer
tl_assert (false);
@ -1668,13 +1669,13 @@ struct scan_shape2shape_same_layer<T, T>
}
void
operator () (const shapes_iterator<T> &subjects, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
operator () (const generic_shape_iterator<T> &subjects, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
{
db::box_scanner<T, int> scanner;
interaction_registration_shape1<T, T> rec (&interactions, intruder_layer);
unsigned int id = subject_id0;
for (shapes_iterator<T> i = subjects; !i.at_end (); ++i) {
for (generic_shape_iterator<T> i = subjects; !i.at_end (); ++i) {
scanner.insert (i.operator-> (), id++);
}
@ -1715,7 +1716,7 @@ struct scan_shape2shape_different_layers
}
void
operator () (db::Layout *layout, const shapes_iterator<TS> &subjects, const shapes_iterator<TI> &intruders, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) const
operator () (db::Layout *layout, const generic_shape_iterator<TS> &subjects, const generic_shape_iterator<TI> &intruders, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) const
{
db::box_scanner2<TS, int, TI, int> scanner;
interaction_registration_shape2shape<TS, TI> rec (layout, &interactions, intruder_layer);
@ -1737,13 +1738,13 @@ struct scan_shape2shape_different_layers
unsigned int id = subject_id0;
shapes_iterator<TS> is = subjects;
generic_shape_iterator<TS> is = subjects;
is.reset (common_box, true);
for ( ; !is.at_end (); ++is) {
scanner.insert1 (is.operator-> (), id++);
}
shapes_iterator<TI> ii = intruders;
generic_shape_iterator<TI> ii = intruders;
ii.reset (common_box, true);
for (; !ii.at_end (); ++ii) {
scanner.insert2 (ii.operator-> (), interactions.next_id ());
@ -1870,43 +1871,43 @@ template <class TS, class TI, class TR>
void
local_processor<TS, TI, TR>::run_flat (const db::Shapes *subject_shapes, const db::Shapes *intruders, const local_operation<TS, TI, TR> *op, db::Shapes *result_shapes) const
{
std::vector<shapes_iterator<TI> > is;
is.push_back (shapes_iterator<TI> (intruders));
std::vector<generic_shape_iterator<TI> > is;
is.push_back (generic_shape_iterator<TI> (intruders));
std::vector<db::Shapes *> os;
os.push_back (result_shapes);
run_flat (shapes_iterator<TS> (subject_shapes), is, op, os);
run_flat (generic_shape_iterator<TS> (subject_shapes), is, op, os);
}
template <class TS, class TI, class TR>
void
local_processor<TS, TI, TR>::run_flat (const db::Shapes *subject_shapes, const std::vector<const db::Shapes *> &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const
{
std::vector<shapes_iterator<TI> > is;
std::vector<generic_shape_iterator<TI> > is;
is.reserve (intruders.size ());
for (std::vector<const db::Shapes *>::const_iterator i = intruders.begin (); i != intruders.end (); ++i) {
is.push_back (shapes_iterator<TI> (*i));
is.push_back (generic_shape_iterator<TI> (*i));
}
run_flat (shapes_iterator<TS> (subject_shapes), is, op, result_shapes);
run_flat (generic_shape_iterator<TS> (subject_shapes), is, op, result_shapes);
}
template <class TS, class TI, class TR>
void
local_processor<TS, TI, TR>::run_flat (const shapes_iterator<TS> &subjects, const std::vector<shapes_iterator<TI> > &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const
local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subjects, const std::vector<generic_shape_iterator<TI> > &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const
{
tl_assert (mp_subject_top == 0);
tl_assert (mp_intruder_top == 0);
shape_interactions<TS, TI> interactions;
for (typename std::vector<shapes_iterator<TI> >::const_iterator il = intruders.begin (); il != intruders.end (); ++il) {
for (typename std::vector<generic_shape_iterator<TI> >::const_iterator il = intruders.begin (); il != intruders.end (); ++il) {
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
// range for the subject shapes.
unsigned int subject_id0 = 0;
for (shapes_iterator<TS> i = subjects; !i.at_end (); ++i) {
for (generic_shape_iterator<TS> i = subjects; !i.at_end (); ++i) {
unsigned int id = interactions.next_id ();
if (subject_id0 == 0) {

View File

@ -29,6 +29,7 @@
#include "dbLayout.h"
#include "dbLocalOperation.h"
#include "dbGenericShapeIterator.h"
#include "tlThreadedWorkers.h"
#include "tlProgress.h"
@ -371,290 +372,6 @@ public:
}
};
template <class T> unsigned int shape_flags ();
template <>
inline unsigned int shape_flags<db::PolygonRef> ()
{
return 1 << db::ShapeIterator::PolygonRef;
}
template <>
inline unsigned int shape_flags<db::Edge> ()
{
return db::ShapeIterator::Edges;
}
template <>
inline unsigned int shape_flags<db::TextRef> ()
{
return db::ShapeIterator::Texts;
}
template <class T>
class DB_PUBLIC iterator_delegate_base
{
public:
iterator_delegate_base () { }
virtual ~iterator_delegate_base () { }
virtual void do_reset (const db::Box &region, bool overlapping) = 0;
virtual db::Box bbox () const { return db::Box::world (); }
virtual bool at_end () const = 0;
virtual void inc () = 0;
virtual const T *get () const = 0;
virtual iterator_delegate_base<T> *clone () const = 0;
virtual bool equals (const iterator_delegate_base<T> *other) const = 0;
};
template <class Iter>
class DB_PUBLIC iterator_delegate2
: public iterator_delegate_base<typename Iter::value_type>
{
public:
typedef typename Iter::value_type value_type;
iterator_delegate2 (const Iter &from, const Iter &to)
: m_iter (from), m_from (from), m_to (to)
{ }
virtual void do_reset (const db::Box &, bool)
{
m_iter = m_from;
}
virtual bool at_end () const
{
return m_iter == m_to;
}
virtual void inc ()
{
++m_iter;
}
virtual const value_type *get () const
{
return m_iter.operator-> ();
}
iterator_delegate_base<value_type> *clone () const
{
return new iterator_delegate2<Iter> (*this);
}
virtual bool equals (const iterator_delegate_base<value_type> *other) const
{
const iterator_delegate2<Iter> *o = dynamic_cast<const iterator_delegate2<Iter> *> (other);
return o && o->m_iter == m_iter;
}
private:
Iter m_iter, m_from, m_to;
};
template <class Iter>
class DB_PUBLIC iterator_delegate1
: public iterator_delegate_base<typename Iter::value_type>
{
public:
typedef typename Iter::value_type value_type;
iterator_delegate1 (const Iter &from)
: m_iter (from), m_from (from)
{ }
virtual void do_reset (const db::Box &, bool)
{
m_iter = m_from;
}
virtual bool at_end () const
{
return m_iter.at_end ();
}
virtual void inc ()
{
++m_iter;
}
virtual const value_type &get () const
{
return *m_iter;
}
iterator_delegate_base<value_type> *clone () const
{
return new iterator_delegate1<Iter> (*this);
}
virtual bool equals (const iterator_delegate_base<value_type> *other) const
{
const iterator_delegate1<Iter> *o = dynamic_cast<const iterator_delegate1<Iter> *> (other);
return o && o->m_iter == m_iter;
}
private:
Iter m_iter, m_from;
};
template <class T>
class DB_PUBLIC shapes_iterator_delegate
: public iterator_delegate_base<T>
{
public:
shapes_iterator_delegate (const db::Shapes *shapes)
: mp_shapes (shapes), m_iter (mp_shapes->begin (shape_flags<T> ()))
{
// .. nothing yet ..
}
virtual void do_reset (const db::Box &box, bool overlapping)
{
if (box == db::Box::world ()) {
m_iter = mp_shapes->begin (shape_flags<T> ());
} else {
if (mp_shapes->is_bbox_dirty ()) {
const_cast<db::Shapes *> (mp_shapes)->update ();
}
if (overlapping) {
m_iter = mp_shapes->begin_overlapping (box, shape_flags<T> ());
} else {
m_iter = mp_shapes->begin_touching (box, shape_flags<T> ());
}
}
}
virtual bool at_end () const
{
return m_iter.at_end ();
}
virtual void inc ()
{
++m_iter;
}
virtual const T *get () const
{
return m_iter->basic_ptr (typename T::tag ());
}
iterator_delegate_base<T> *clone () const
{
return new shapes_iterator_delegate<T> (*this);
}
virtual db::Box bbox () const
{
if (mp_shapes->is_bbox_dirty ()) {
const_cast<db::Shapes *> (mp_shapes)->update ();
}
return mp_shapes->bbox ();
}
virtual bool equals (const iterator_delegate_base<T> *other) const
{
const shapes_iterator_delegate<T> *o = dynamic_cast<const shapes_iterator_delegate<T> *> (other);
return o && o->mp_shapes == mp_shapes && o->m_iter.at_end () == m_iter.at_end () && (m_iter.at_end () || o->m_iter->basic_ptr (typename T::tag ()) == m_iter->basic_ptr (typename T::tag ()));
}
private:
const db::Shapes *mp_shapes;
db::Shapes::shape_iterator m_iter;
shapes_iterator_delegate (const shapes_iterator_delegate &other)
: mp_shapes (other.mp_shapes), m_iter (other.m_iter)
{
// .. nothing yet ..
}
};
template <class T>
class DB_PUBLIC shapes_iterator
{
public:
template <class Iter>
shapes_iterator (const Iter &from, const Iter &to)
: mp_delegate (new iterator_delegate2<Iter> (from, to))
{ }
template <class Iter>
shapes_iterator (const Iter &from)
: mp_delegate (new iterator_delegate1<Iter> (from))
{ }
shapes_iterator (const db::Shapes *shapes)
: mp_delegate (new shapes_iterator_delegate<T> (shapes))
{ }
shapes_iterator (const shapes_iterator<T> &other)
: mp_delegate (other.mp_delegate->clone ())
{ }
shapes_iterator &operator= (const shapes_iterator &other)
{
delete mp_delegate;
mp_delegate = other.mp_delegate->clone ();
}
bool operator== (const shapes_iterator<T> &other) const
{
return mp_delegate->equals (other.mp_delegate);
}
template <class TO>
bool operator== (const shapes_iterator<TO> &) const
{
return false;
}
~shapes_iterator ()
{
delete mp_delegate;
}
const T &operator* () const
{
return *mp_delegate->get ();
}
const T *operator-> () const
{
return mp_delegate->get ();
}
shapes_iterator &operator++ ()
{
mp_delegate->inc ();
return *this;
}
bool at_end () const
{
return mp_delegate->at_end ();
}
void reset ()
{
mp_delegate->do_reset (db::Box::world (), false);
}
void reset (const db::Box &box, bool overlapping)
{
mp_delegate->do_reset (box, overlapping);
}
db::Box bbox () const
{
return mp_delegate->bbox ();
}
public:
iterator_delegate_base<T> *mp_delegate;
};
template <class TS, class TI, class TR>
class DB_PUBLIC local_processor
{
@ -669,7 +386,7 @@ public:
void run_flat (const db::Shapes *subject_shapes, const db::Shapes *intruders, const local_operation<TS, TI, TR> *op, db::Shapes *result_shapes) const;
void run_flat (const db::Shapes *subjects, const std::vector<const db::Shapes *> &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
void run_flat (const shapes_iterator<TS> &subjects, const std::vector<shapes_iterator<TI> > &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
void run_flat (const generic_shape_iterator<TS> &subjects, const std::vector<generic_shape_iterator<TI> > &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
void set_description (const std::string &d)
{

View File

@ -57,7 +57,7 @@ namespace
virtual void increment ()
{
inc ();
do_increment ();
set ();
}
@ -71,6 +71,27 @@ namespace
return new OriginalLayerRegionIterator (*this);
}
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
{
const OriginalLayerRegionIterator *o = dynamic_cast<const OriginalLayerRegionIterator *> (other);
return o && o->m_rec_iter == m_rec_iter && o->m_iter_trans.equal (m_iter_trans);
}
virtual void do_reset (const db::Box &region, bool overlapping)
{
if (region == db::Box::world ()) {
m_rec_iter.set_region (region);
} else {
m_rec_iter.set_region (m_iter_trans.inverted () * region);
}
m_rec_iter.set_overlapping (overlapping);
}
virtual db::Box bbox () const
{
return m_iter_trans * m_rec_iter.bbox ();
}
private:
friend class Region;
@ -89,7 +110,7 @@ namespace
}
}
void inc ()
void do_increment ()
{
if (! m_rec_iter.at_end ()) {
++m_rec_iter;
@ -172,7 +193,7 @@ OriginalLayerRegion::begin_merged () const
return begin ();
} else {
ensure_merged_polygons_valid ();
return new FlatRegionIterator (m_merged_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (), m_merged_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end ());
return new FlatRegionIterator (& m_merged_polygons);
}
}

View File

@ -47,19 +47,14 @@ class TransformationReducer;
* The iterator delivers the polygons of the region
*/
class DB_PUBLIC RegionIterator
: public generic_shape_iterator<db::Polygon>
{
public:
typedef RegionIteratorDelegate::value_type value_type;
typedef const value_type &reference;
typedef const value_type *pointer;
typedef std::forward_iterator_tag iterator_category;
typedef void difference_type;
/**
* @brief Default constructor
*/
RegionIterator ()
: mp_delegate (0)
: generic_shape_iterator<db::Polygon> ()
{
// .. nothing yet ..
}
@ -69,27 +64,18 @@ public:
* The iterator will take ownership over the delegate
*/
RegionIterator (RegionIteratorDelegate *delegate)
: mp_delegate (delegate)
: generic_shape_iterator<db::Polygon> (delegate)
{
// .. nothing yet ..
}
/**
* @brief Destructor
*/
~RegionIterator ()
{
delete mp_delegate;
mp_delegate = 0;
}
/**
* @brief Copy constructor and assignment
*/
RegionIterator (const RegionIterator &other)
: mp_delegate (0)
: generic_shape_iterator<db::Polygon> (static_cast<const generic_shape_iterator<db::Polygon> &> (other))
{
operator= (other);
// .. nothing yet ..
}
/**
@ -97,52 +83,18 @@ public:
*/
RegionIterator &operator= (const RegionIterator &other)
{
if (this != &other) {
delete mp_delegate;
mp_delegate = other.mp_delegate ? other.mp_delegate->clone () : 0;
}
generic_shape_iterator<db::Polygon>::operator= (other);
return *this;
}
/**
* @Returns true, if the iterator is at the end
*/
bool at_end () const
{
return mp_delegate == 0 || mp_delegate->at_end ();
}
/**
* @brief Increment
*/
RegionIterator &operator++ ()
{
if (mp_delegate) {
mp_delegate->increment ();
}
generic_shape_iterator<db::Polygon>::operator++ ();
return *this;
}
/**
* @brief Access
*/
reference operator* () const
{
const value_type *value = operator-> ();
tl_assert (value != 0);
return *value;
}
/**
* @brief Access
*/
pointer operator-> () const
{
return mp_delegate ? mp_delegate->get () : 0;
}
private:
RegionIteratorDelegate *mp_delegate;
};
/**

View File

@ -32,6 +32,7 @@
#include "dbEdgePairs.h"
#include "dbEdgePairRelations.h"
#include "dbShapeCollection.h"
#include "dbGenericShapeIterator.h"
#include <list>
@ -142,19 +143,7 @@ typedef shape_collection_processor<db::Polygon, db::EdgePair> PolygonToEdgePairP
/**
* @brief The region iterator delegate
*/
class DB_PUBLIC RegionIteratorDelegate
{
public:
RegionIteratorDelegate () { }
virtual ~RegionIteratorDelegate () { }
typedef db::Polygon value_type;
virtual bool at_end () const = 0;
virtual void increment () = 0;
virtual const value_type *get () const = 0;
virtual RegionIteratorDelegate *clone () const = 0;
};
typedef db::generic_shape_iterator_delegate_base <db::Polygon> RegionIteratorDelegate;
/**
* @brief The delegate for the actual region implementation

23
src/db/db/dbShapeFlags.cc Normal file
View File

@ -0,0 +1,23 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 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
*/
#include "dbShapeFlags.h"

79
src/db/db/dbShapeFlags.h Normal file
View File

@ -0,0 +1,79 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 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_dbShapeFlags
#define HDR_dbShapeFlags
#include "dbCommon.h"
#include "dbShapes.h"
namespace db
{
template <class T> unsigned int shape_flags ();
template <>
inline unsigned int shape_flags<db::PolygonRef> ()
{
return 1 << db::ShapeIterator::PolygonRef;
}
template <>
inline unsigned int shape_flags<db::Box> ()
{
return 1 << db::ShapeIterator::Box;
}
template <>
inline unsigned int shape_flags<db::Path> ()
{
return 1 << db::ShapeIterator::Path;
}
template <>
inline unsigned int shape_flags<db::Polygon> ()
{
return 1 << db::ShapeIterator::Polygon;
}
template <>
inline unsigned int shape_flags<db::Edge> ()
{
return 1 << db::ShapeIterator::Edge;
}
template <>
inline unsigned int shape_flags<db::Text> ()
{
return 1 << db::ShapeIterator::Text;
}
template <>
inline unsigned int shape_flags<db::TextRef> ()
{
return 1 << db::ShapeIterator::TextRef;
}
}
#endif