mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
8a122c8a7d
commit
dfe67178dc
|
|
@ -26,6 +26,50 @@
|
|||
namespace pex
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
std::string
|
||||
RNode::to_string () const
|
||||
{
|
||||
std::string res;
|
||||
switch (type) {
|
||||
default:
|
||||
res += "$" + tl::to_string (port_index);
|
||||
break;
|
||||
case VertexPort:
|
||||
res += "V" + tl::to_string (port_index);
|
||||
break;
|
||||
case PolygonPort:
|
||||
res += "P" + tl::to_string (port_index);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
std::string
|
||||
RElement::to_string () const
|
||||
{
|
||||
std::string res = "R ";
|
||||
if (a ()) {
|
||||
res += a ()->to_string ();
|
||||
} else {
|
||||
res += "(nil)";
|
||||
}
|
||||
res += " ";
|
||||
if (b ()) {
|
||||
res += b ()->to_string ();
|
||||
} else {
|
||||
res += "(nil)";
|
||||
}
|
||||
res += " ";
|
||||
res += tl::sprintf ("%.6g", resistance ());
|
||||
return res;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
RNetwork::RNetwork ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -36,10 +80,23 @@ RNetwork::~RNetwork ()
|
|||
clear ();
|
||||
}
|
||||
|
||||
std::string
|
||||
RNetwork::to_string () const
|
||||
{
|
||||
std::string res;
|
||||
for (auto e = m_elements.begin (); e != m_elements.end (); ++e) {
|
||||
if (! res.empty ()) {
|
||||
res += "\n";
|
||||
}
|
||||
res += e->to_string ();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
RNetwork::clear ()
|
||||
{
|
||||
m_elements.clear (); // must come before m_nodes
|
||||
m_elements.clear (); // must happen before m_nodes
|
||||
m_nodes.clear ();
|
||||
m_elements_by_nodes.clear ();
|
||||
m_nodes_by_type.clear ();
|
||||
|
|
@ -51,7 +108,7 @@ std::map<std::pair<RNode::node_type, unsigned int>, RNode *> m_nodes;
|
|||
RNode *
|
||||
RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
||||
{
|
||||
if (type != RNode::INTERNAL) {
|
||||
if (type != RNode::Internal) {
|
||||
|
||||
auto i = m_nodes_by_type.find (std::make_pair (type, port_index));
|
||||
if (i != m_nodes_by_type.end ()) {
|
||||
|
|
@ -60,7 +117,7 @@ RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
|||
|
||||
} else {
|
||||
|
||||
RNode *new_node = new RNode (type, db::DBox (), port_index);
|
||||
RNode *new_node = new RNode (this, type, db::DBox (), port_index);
|
||||
m_nodes.push_back (new_node);
|
||||
m_nodes_by_type.insert (std::make_pair (std::make_pair (type, port_index), new_node));
|
||||
|
||||
|
|
@ -69,7 +126,7 @@ RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
|||
|
||||
} else {
|
||||
|
||||
RNode *new_node = new RNode (type, db::DBox (), port_index);
|
||||
RNode *new_node = new RNode (this, type, db::DBox (), port_index);
|
||||
m_nodes.push_back (new_node);
|
||||
return new_node;
|
||||
|
||||
|
|
@ -87,13 +144,15 @@ RNetwork::create_element (double conductivity, RNode *a, RNode *b)
|
|||
|
||||
} else {
|
||||
|
||||
RElement *element = new RElement (conductivity, a, b);
|
||||
a->elements.push_back (element);
|
||||
element->m_ia = --a->elements.end ();
|
||||
b->elements.push_back (element);
|
||||
element->m_ia = --b->elements.end ();
|
||||
|
||||
RElement *element = new RElement (this, conductivity, a, b);
|
||||
m_elements.push_back (element);
|
||||
m_elements_by_nodes.insert (std::make_pair (std::make_pair (a, b), element));
|
||||
|
||||
a->m_elements.push_back (element);
|
||||
element->m_ia = --a->m_elements.end ();
|
||||
b->m_elements.push_back (element);
|
||||
element->m_ib = --b->m_elements.end ();
|
||||
|
||||
return element;
|
||||
|
||||
}
|
||||
|
|
@ -102,9 +161,9 @@ RNetwork::create_element (double conductivity, RNode *a, RNode *b)
|
|||
void
|
||||
RNetwork::remove_node (RNode *node)
|
||||
{
|
||||
tl_assert (node->type == RNode::INTERNAL);
|
||||
while (! node->elements.empty ()) {
|
||||
remove_element (const_cast<RElement *> (node->elements.front ()));
|
||||
tl_assert (node->type == RNode::Internal);
|
||||
while (! node->m_elements.empty ()) {
|
||||
delete const_cast<RElement *> (node->m_elements.front ());
|
||||
}
|
||||
delete node;
|
||||
}
|
||||
|
|
@ -112,19 +171,20 @@ RNetwork::remove_node (RNode *node)
|
|||
void
|
||||
RNetwork::remove_element (RElement *element)
|
||||
{
|
||||
RNode *a = const_cast<RNode *> (element->a);
|
||||
RNode *b = const_cast<RNode *> (element->b);
|
||||
RNode *a = const_cast<RNode *> (element->a ());
|
||||
RNode *b = const_cast<RNode *> (element->b ());
|
||||
|
||||
delete element;
|
||||
|
||||
if (a && a->type == RNode::INTERNAL && a->elements.empty ()) {
|
||||
if (a && a->type == RNode::Internal && a->m_elements.empty ()) {
|
||||
delete a;
|
||||
}
|
||||
if (b && b->type == RNode::INTERNAL && b->elements.empty ()) {
|
||||
if (b && b->type == RNode::Internal && b->m_elements.empty ()) {
|
||||
delete b;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
RExtractor::RExtractor ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,28 +39,36 @@ namespace pex
|
|||
|
||||
class RElement;
|
||||
class RNode;
|
||||
class RNetwork;
|
||||
|
||||
struct PEX_PUBLIC RNode
|
||||
: public tl::list_node<RNode>
|
||||
{
|
||||
public:
|
||||
enum node_type {
|
||||
INTERNAL,
|
||||
VERTEX_PORT,
|
||||
POLYGON_PORT
|
||||
Internal,
|
||||
VertexPort,
|
||||
PolygonPort
|
||||
};
|
||||
|
||||
node_type type;
|
||||
db::DBox location;
|
||||
unsigned int port_index;
|
||||
mutable std::list<const RElement *> elements;
|
||||
|
||||
const std::list<const RElement *> &elements () const
|
||||
{
|
||||
return m_elements;
|
||||
}
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
protected:
|
||||
friend class RNetwork;
|
||||
friend class RElement;
|
||||
friend class tl::list_impl<RNode, false>;
|
||||
|
||||
RNode (node_type _type, const db::DBox &_location, unsigned int _port_index)
|
||||
: type (_type), location (_location), port_index (_port_index)
|
||||
RNode (RNetwork *network, node_type _type, const db::DBox &_location, unsigned int _port_index)
|
||||
: type (_type), location (_location), port_index (_port_index), mp_network (network)
|
||||
{ }
|
||||
|
||||
~RNode () { }
|
||||
|
|
@ -68,39 +76,48 @@ protected:
|
|||
private:
|
||||
RNode (const RNode &other);
|
||||
RNode &operator= (const RNode &other);
|
||||
|
||||
RNetwork *mp_network;
|
||||
mutable std::list<const RElement *> m_elements;
|
||||
};
|
||||
|
||||
struct PEX_PUBLIC RElement
|
||||
: public tl::list_node<RElement>
|
||||
{
|
||||
double conductivity;
|
||||
const RNode *a, *b;
|
||||
|
||||
const RNode *a () const { return mp_a; }
|
||||
const RNode *b () const { return mp_b; }
|
||||
|
||||
double resistance () const
|
||||
{
|
||||
return 1.0 / conductivity;
|
||||
}
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
protected:
|
||||
friend class RNetwork;
|
||||
friend class tl::list_impl<RElement, false>;
|
||||
|
||||
RElement (double _conductivity, const RNode *_a, const RNode *_b)
|
||||
: conductivity (_conductivity), a (_a), b (_b)
|
||||
RElement (RNetwork *network, double _conductivity, const RNode *a, const RNode *b)
|
||||
: conductivity (_conductivity), mp_network (network), mp_a (a), mp_b (b)
|
||||
{ }
|
||||
|
||||
~RElement ()
|
||||
{
|
||||
if (a) {
|
||||
a->elements.erase (m_ia);
|
||||
if (mp_a) {
|
||||
mp_a->m_elements.erase (m_ia);
|
||||
}
|
||||
if (b) {
|
||||
b->elements.erase (m_ib);
|
||||
if (mp_b) {
|
||||
mp_b->m_elements.erase (m_ib);
|
||||
}
|
||||
a = b = 0;
|
||||
mp_a = mp_b = 0;
|
||||
}
|
||||
|
||||
std::list<const RElement *>::iterator m_ia, m_ib;
|
||||
RNetwork *mp_network;
|
||||
const RNode *mp_a, *mp_b;
|
||||
|
||||
private:
|
||||
RElement (const RElement &other);
|
||||
|
|
@ -108,6 +125,7 @@ private:
|
|||
};
|
||||
|
||||
class PEX_PUBLIC RNetwork
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
RNetwork ();
|
||||
|
|
@ -119,6 +137,8 @@ public:
|
|||
void remove_node (RNode *node);
|
||||
void clear ();
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
private:
|
||||
tl::list<RNode, false> m_nodes;
|
||||
tl::list<RElement, false> m_elements;
|
||||
|
|
|
|||
|
|
@ -24,8 +24,53 @@
|
|||
#include "pexRExtractor.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
TEST(1)
|
||||
TEST(network_basic)
|
||||
{
|
||||
// @@@
|
||||
pex::RNetwork rn;
|
||||
EXPECT_EQ (rn.to_string (), "");
|
||||
|
||||
pex::RNode *n1 = rn.create_node (pex::RNode::Internal, 1);
|
||||
pex::RNode *n2 = rn.create_node (pex::RNode::Internal, 2);
|
||||
/* pex::RElement *e12 = */ rn.create_element (0.5, n1, n2);
|
||||
|
||||
EXPECT_EQ (rn.to_string (),
|
||||
"R $1 $2 2"
|
||||
);
|
||||
|
||||
pex::RNode *n3 = rn.create_node (pex::RNode::Internal, 3);
|
||||
/* pex::RElement *e13 = */ rn.create_element (0.25, n1, n3);
|
||||
pex::RElement *e23 = rn.create_element (1.0, n2, n3);
|
||||
|
||||
EXPECT_EQ (rn.to_string (),
|
||||
"R $1 $2 2\n"
|
||||
"R $1 $3 4\n"
|
||||
"R $2 $3 1"
|
||||
);
|
||||
|
||||
pex::RElement *e23b = rn.create_element (4.0, n2, n3);
|
||||
EXPECT_EQ (e23 == e23b, true);
|
||||
|
||||
EXPECT_EQ (rn.to_string (),
|
||||
"R $1 $2 2\n"
|
||||
"R $1 $3 4\n"
|
||||
"R $2 $3 0.2"
|
||||
);
|
||||
|
||||
rn.remove_element (e23);
|
||||
|
||||
EXPECT_EQ (rn.to_string (),
|
||||
"R $1 $2 2\n"
|
||||
"R $1 $3 4"
|
||||
);
|
||||
|
||||
rn.remove_node (n3);
|
||||
|
||||
EXPECT_EQ (rn.to_string (),
|
||||
"R $1 $2 2"
|
||||
);
|
||||
|
||||
rn.clear ();
|
||||
|
||||
EXPECT_EQ (rn.to_string (), "");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue