mirror of https://github.com/KLayout/klayout.git
Shape#hash and Shape#< allow using Shape objects as hash keys
This commit is contained in:
parent
69423e37ac
commit
c43b70b783
|
|
@ -43,6 +43,7 @@
|
||||||
using them to select edges.
|
using them to select edges.
|
||||||
* Enhancement: New RBA/pya Features
|
* Enhancement: New RBA/pya Features
|
||||||
- Main window title: MainWindow#title (property)
|
- Main window title: MainWindow#title (property)
|
||||||
|
- MainWindow#synchronous (getter added)
|
||||||
- LayoutView#is_dirty?
|
- LayoutView#is_dirty?
|
||||||
- Triangulation: Region#delaunay
|
- Triangulation: Region#delaunay
|
||||||
- Quality rasterizer: Region#rasterize
|
- Quality rasterizer: Region#rasterize
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include "dbShape.h"
|
#include "dbShape.h"
|
||||||
#include "dbBoxConvert.h"
|
#include "dbBoxConvert.h"
|
||||||
#include "dbPolygonTools.h"
|
#include "dbPolygonTools.h"
|
||||||
|
#include "dbHash.h"
|
||||||
#include "tlCpp.h"
|
#include "tlCpp.h"
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
|
|
@ -862,6 +863,24 @@ Shape::box_type Shape::rectangle () const
|
||||||
return box_type ();
|
return box_type ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
Shape::hash_value () const
|
||||||
|
{
|
||||||
|
size_t h = size_t (m_type);
|
||||||
|
h = std::hcombine (h, std::hfunc (m_trans));
|
||||||
|
|
||||||
|
if (m_stable) {
|
||||||
|
// Use the bytes of the iterator binary pattern (see operator<)
|
||||||
|
for (unsigned int i = 0; i < sizeof (tl::reuse_vector<box_type>::const_iterator); ++i) {
|
||||||
|
h = std::hcombine (h, size_t (m_generic.iter[i]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
h = std::hcombine (h, size_t (m_generic.any));
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Shape::to_string () const
|
Shape::to_string () const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2769,6 +2769,11 @@ public:
|
||||||
return m_trans < d.m_trans;
|
return m_trans < d.m_trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hash value
|
||||||
|
*/
|
||||||
|
size_t hash_value () const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert to a string
|
* @brief Convert to a string
|
||||||
*/
|
*/
|
||||||
|
|
@ -2837,6 +2842,21 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace db
|
} // namespace db
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
// provide a template specialization for std::hash<T>
|
||||||
|
template <>
|
||||||
|
struct hash <db::Shape>
|
||||||
|
{
|
||||||
|
size_t operator() (const db::Shape &s) const
|
||||||
|
{
|
||||||
|
return s.hash_value ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2131,6 +2131,21 @@ Class<db::Shape> decl_Shape ("db", "Shape",
|
||||||
"Equality of shapes is not specified by the identity of the objects but by the\n"
|
"Equality of shapes is not specified by the identity of the objects but by the\n"
|
||||||
"identity of the pointers - both shapes must refer to the same object.\n"
|
"identity of the pointers - both shapes must refer to the same object.\n"
|
||||||
) +
|
) +
|
||||||
|
gsi::method ("<", &db::Shape::operator<, gsi::arg ("other"),
|
||||||
|
"@brief Less operator\n"
|
||||||
|
"\n"
|
||||||
|
"The less operator implementation is based on pointers and not strictly reproducible."
|
||||||
|
"However, it is good enough so Shape objects can serve as keys in hashes (see also \\hash).\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.29."
|
||||||
|
) +
|
||||||
|
gsi::method ("hash", &db::Shape::hash_value,
|
||||||
|
"@brief Hash function\n"
|
||||||
|
"\n"
|
||||||
|
"The hash function enables Shape objects as keys in hashes.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.29."
|
||||||
|
) +
|
||||||
gsi::method ("to_s", &db::Shape::to_string,
|
gsi::method ("to_s", &db::Shape::to_string,
|
||||||
"@brief Create a string showing the contents of the reference\n"
|
"@brief Create a string showing the contents of the reference\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ void run_pythontest (tl::TestBase *_this, const std::string &fn)
|
||||||
PYTHONTEST (kwargs, "kwargs.py")
|
PYTHONTEST (kwargs, "kwargs.py")
|
||||||
PYTHONTEST (dbLayoutTest, "dbLayoutTest.py")
|
PYTHONTEST (dbLayoutTest, "dbLayoutTest.py")
|
||||||
PYTHONTEST (dbRegionTest, "dbRegionTest.py")
|
PYTHONTEST (dbRegionTest, "dbRegionTest.py")
|
||||||
|
PYTHONTEST (dbShapesTest, "dbShapesTest.py")
|
||||||
PYTHONTEST (dbReaders, "dbReaders.py")
|
PYTHONTEST (dbReaders, "dbReaders.py")
|
||||||
PYTHONTEST (dbPCellsTest, "dbPCells.py")
|
PYTHONTEST (dbPCellsTest, "dbPCells.py")
|
||||||
PYTHONTEST (dbPolygonTest, "dbPolygonTest.py")
|
PYTHONTEST (dbPolygonTest, "dbPolygonTest.py")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
# KLayout Layout Viewer
|
||||||
|
# Copyright (C) 2006-2024 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
|
||||||
|
|
||||||
|
|
||||||
|
import pya
|
||||||
|
import unittest
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
class DBShapesTest(unittest.TestCase):
|
||||||
|
|
||||||
|
# Shape objects as hashes
|
||||||
|
def test_12(self):
|
||||||
|
|
||||||
|
s = pya.Shapes()
|
||||||
|
s1 = s.insert(pya.Box(1, 2, 3, 4))
|
||||||
|
s2 = s.insert(pya.Polygon(pya.Box(1, 2, 3, 4)))
|
||||||
|
s3 = s.insert(pya.SimplePolygon(pya.Box(1, 2, 3, 4)))
|
||||||
|
|
||||||
|
self.assertEqual(s1.hash != s2.hash, True) # let's hope so ...
|
||||||
|
self.assertEqual(s1.hash != s3.hash, True)
|
||||||
|
self.assertEqual(s2.hash != s3.hash, True)
|
||||||
|
|
||||||
|
self.assertEqual(s1 < s2 or s2 < s1, True)
|
||||||
|
self.assertEqual(s1 < s3 or s3 < s1, True)
|
||||||
|
self.assertEqual(s2 < s3 or s3 < s2, True)
|
||||||
|
|
||||||
|
h = {}
|
||||||
|
h[s1] = 1
|
||||||
|
h[s2] = 2
|
||||||
|
h[s3] = 3
|
||||||
|
|
||||||
|
self.assertEqual(len(h), 3)
|
||||||
|
|
||||||
|
self.assertEqual(h[s1], 1)
|
||||||
|
self.assertEqual(h[s2], 2)
|
||||||
|
self.assertEqual(h[s3], 3)
|
||||||
|
|
||||||
|
# run unit tests
|
||||||
|
if __name__ == '__main__':
|
||||||
|
suite = unittest.TestLoader().loadTestsFromTestCase(DBShapesTest)
|
||||||
|
|
||||||
|
if not unittest.TextTestRunner(verbosity = 1).run(suite).wasSuccessful():
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
@ -1627,6 +1627,35 @@ class DBShapes_TestClass < TestBase
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Shape objects as hashes
|
||||||
|
def test_12
|
||||||
|
|
||||||
|
s = RBA::Shapes::new
|
||||||
|
s1 = s.insert(RBA::Box::new(1, 2, 3, 4))
|
||||||
|
s2 = s.insert(RBA::Polygon::new(RBA::Box::new(1, 2, 3, 4)))
|
||||||
|
s3 = s.insert(RBA::SimplePolygon::new(RBA::Box::new(1, 2, 3, 4)))
|
||||||
|
|
||||||
|
assert_equal(s1.hash != s2.hash, true) # let's hope so ...
|
||||||
|
assert_equal(s1.hash != s3.hash, true)
|
||||||
|
assert_equal(s2.hash != s3.hash, true)
|
||||||
|
|
||||||
|
assert_equal(s1 < s2 || s2 < s1, true)
|
||||||
|
assert_equal(s1 < s3 || s3 < s1, true)
|
||||||
|
assert_equal(s2 < s3 || s3 < s2, true)
|
||||||
|
|
||||||
|
h = {}
|
||||||
|
h[s1] = 1
|
||||||
|
h[s2] = 2
|
||||||
|
h[s3] = 3
|
||||||
|
|
||||||
|
assert_equal(h.size, 3)
|
||||||
|
|
||||||
|
assert_equal(h[s1], 1)
|
||||||
|
assert_equal(h[s2], 2)
|
||||||
|
assert_equal(h[s3], 3)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
load("test_epilogue.rb")
|
load("test_epilogue.rb")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue