From dfe67178dc1c87327e88bff56a0a23dd630841c3 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 19 Apr 2025 16:14:15 +0200 Subject: [PATCH] WIP --- src/pex/pex/pexRExtractor.cc | 94 +++++++++++++++++++----- src/pex/pex/pexRExtractor.h | 48 ++++++++---- src/pex/unit_tests/pexRExtractorTests.cc | 49 +++++++++++- 3 files changed, 158 insertions(+), 33 deletions(-) diff --git a/src/pex/pex/pexRExtractor.cc b/src/pex/pex/pexRExtractor.cc index 5d7a30eab..614e6f009 100644 --- a/src/pex/pex/pexRExtractor.cc +++ b/src/pex/pex/pexRExtractor.cc @@ -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, 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 (node->elements.front ())); + tl_assert (node->type == RNode::Internal); + while (! node->m_elements.empty ()) { + delete const_cast (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 (element->a); - RNode *b = const_cast (element->b); + RNode *a = const_cast (element->a ()); + RNode *b = const_cast (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 () { diff --git a/src/pex/pex/pexRExtractor.h b/src/pex/pex/pexRExtractor.h index dccc95616..87a2f2565 100644 --- a/src/pex/pex/pexRExtractor.h +++ b/src/pex/pex/pexRExtractor.h @@ -39,28 +39,36 @@ namespace pex class RElement; class RNode; +class RNetwork; struct PEX_PUBLIC RNode : public tl::list_node { 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 elements; + + const std::list &elements () const + { + return m_elements; + } + + std::string to_string () const; protected: friend class RNetwork; + friend class RElement; friend class tl::list_impl; - 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 m_elements; }; struct PEX_PUBLIC RElement : public tl::list_node { 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 (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::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 m_nodes; tl::list m_elements; diff --git a/src/pex/unit_tests/pexRExtractorTests.cc b/src/pex/unit_tests/pexRExtractorTests.cc index c3ad86a08..3915e8337 100644 --- a/src/pex/unit_tests/pexRExtractorTests.cc +++ b/src/pex/unit_tests/pexRExtractorTests.cc @@ -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 (), ""); }