Hash functions and fuzzy compare for RBA

RBA now provides a hash method for Box, Edge, EdgePair, Trans,
Polygon, SimplePolygon, CellInstArray, LayerInfo, Path, Text,
Point and Vector.

eql? is mapped to ==.

==, != and < act "fuzzy" for the double-typed variants.

Hence, these objects can be used as hash keys now.
This commit is contained in:
Matthias Koefferlein 2017-07-09 22:40:56 +02:00
parent 8396463daf
commit 02819c5f1e
36 changed files with 1921 additions and 207 deletions

View File

@ -168,6 +168,14 @@ struct box
*/
bool equal (const box_type &b) const;
/**
* @brief Fuzzy comparison of boxes
*/
bool not_equal (const box_type &b) const
{
return !equal (b);
}
/**
* @brief Fuzzy "less" comparison of points
*/

View File

@ -165,6 +165,30 @@ public:
return !operator== (b);
}
/**
* @brief A fuzzy less operator to establish a sorting order.
*/
bool less (const edge<C> &b) const
{
return m_p1.less (b.m_p1) || (m_p1.equal (b.m_p1) && m_p2.less (b.m_p2));
}
/**
* @brief Fuzzy equality test
*/
bool equal (const edge<C> &b) const
{
return m_p1.equal (b.m_p1) && m_p2.equal (b.m_p2);
}
/**
* @brief Fuzzy inequality test
*/
bool not_equal (const edge<C> &b) const
{
return !equal (b);
}
/**
* @brief A method binding of operator* (mainly for automation purposes)
*/

View File

@ -94,7 +94,7 @@ public:
*/
bool operator< (const edge_pair<C> &b) const
{
return m_first < b.m_first || (m_first == b.m_first && m_first < b.m_first);
return m_first < b.m_first || (m_first == b.m_first && m_second < b.m_second);
}
/**
@ -113,6 +113,30 @@ public:
return !operator== (b);
}
/**
* @brief A fuzzy less operator to establish a sorting order.
*/
bool less (const edge_pair<C> &b) const
{
return m_first.less (b.m_first) || (m_first.equal (b.m_first) && m_second.less (b.m_second));
}
/**
* @brief Fuzzy equality test
*/
bool equal (const edge_pair<C> &b) const
{
return m_first.equal (b.m_first) && m_second.equal (b.m_second);
}
/**
* @brief Fuzzy inequality test
*/
bool not_equal (const edge_pair<C> &b) const
{
return !equal (b);
}
/**
* @brief A method binding of operator* (mainly for automation purposes)
*/

View File

@ -42,7 +42,14 @@ namespace std_ext = std;
#include "dbText.h"
#include "dbPath.h"
#include "dbPolygon.h"
#include "dbTrans.h"
#include "dbEdgePair.h"
#include "dbInstances.h"
#include "dbLayout.h"
#include <string>
#include <functional>
#include <stdint.h>
/**
* This header defines some hash functions for various database objects
@ -86,37 +93,53 @@ namespace DB_HASH_NAMESPACE
return hcombine (h, hf (t));
}
/**
* @brief Hash value for a point
*/
template <>
struct hash <db::Point>
inline size_t hfunc_coord (db::DCoord d)
{
size_t operator() (const db::Point &o) const
{
return hfunc (o.x (), hfunc (o.y ()));
}
};
return hfunc (int64_t (floor (0.5 + d / db::coord_traits<db::DCoord>::prec ())));
}
inline size_t hfunc_coord (db::Coord d)
{
return hfunc (d);
}
template <class C>
inline size_t hfunc_coord (C d, size_t h)
{
return hcombine (hfunc_coord (d), h);
}
/**
* @brief Hash value for a point
*/
template <>
struct hash <db::Vector>
template <class C>
struct hash <db::point<C> >
{
size_t operator() (const db::Vector &o) const
size_t operator() (const db::point<C> &o) const
{
return hfunc (o.x (), hfunc (o.y ()));
return hfunc_coord (o.x (), hfunc_coord (o.y ()));
}
};
/**
* @brief Hash value for a vector
*/
template <class C>
struct hash <db::vector<C> >
{
size_t operator() (const db::vector<C> &o) const
{
return hfunc_coord (o.x (), hfunc_coord (o.y ()));
}
};
/**
* @brief Hash value for a box
*/
template <>
struct hash <db::Box>
template <class C>
struct hash <db::box<C> >
{
size_t operator() (const db::Box &o) const
size_t operator() (const db::box<C> &o) const
{
return hfunc (o.p1 (), hfunc (o.p2 ()));
}
@ -125,30 +148,40 @@ namespace DB_HASH_NAMESPACE
/**
* @brief Hash value for an edge
*/
template <>
struct hash <db::Edge>
template <class C>
struct hash <db::edge<C> >
{
size_t operator() (const db::Edge &o) const
size_t operator() (const db::edge<C> &o) const
{
return hfunc (o.p1 (), hfunc (o.p2 ()));
}
};
/**
* @brief Hash value for an edge pair
*/
template <class C>
struct hash <db::edge_pair<C> >
{
size_t operator() (const db::edge_pair<C> &o) const
{
return hfunc (o.first (), hfunc (o.second ()));
}
};
/**
* @brief Hash value for a text object
*/
template <>
struct hash <db::Text>
template <class C>
struct hash <db::text<C> >
{
size_t operator() (const db::Text &o) const
size_t operator() (const db::text<C> &o) const
{
size_t h = hfunc (int (o.halign ()));
h = hfunc (int (o.valign ()), h);
h = hfunc (o.trans ().rot (), h);
h = hfunc (o.trans ().disp (), h);
for (const char *cp = o.string (); *cp; ++cp) {
h = hfunc (*cp, h);
}
h = hfunc (hfunc (o.string ()), h);
return h;
}
};
@ -156,33 +189,49 @@ namespace DB_HASH_NAMESPACE
/**
* @brief Hash value for a path
*/
template <>
struct hash <db::Path>
template <class C>
struct hash <db::path<C> >
{
size_t operator() (const db::Path &o) const
size_t operator() (const db::path<C> &o) const
{
size_t h = hfunc (int (o.round ()));
h = hfunc (o.bgn_ext (), h);
h = hfunc (o.end_ext (), h);
h = hfunc (o.width (), h);
for (db::Path::iterator p = o.begin (); p != o.end (); ++p) {
h = hfunc_coord (o.bgn_ext (), h);
h = hfunc_coord (o.end_ext (), h);
h = hfunc_coord (o.width (), h);
for (typename db::path<C>::iterator p = o.begin (); p != o.end (); ++p) {
h = hfunc (*p, h);
}
return h;
}
};
/**
* @brief Hash value for a polygon contour
*/
template <class C>
struct hash <db::polygon_contour<C> >
{
size_t operator() (const db::polygon_contour<C> &o) const
{
size_t h = 0;
for (typename db::polygon_contour<C>::simple_iterator i = o.begin (); i != o.end (); ++i) {
h = hfunc (*i, h);
}
return h;
}
};
/**
* @brief Hash value for a polygon
*/
template <>
struct hash <db::Polygon>
template <class C>
struct hash <db::polygon<C> >
{
size_t operator() (const db::Polygon &o) const
size_t operator() (const db::polygon<C> &o) const
{
size_t h = o.hull ().hash ();
size_t h = hfunc (o.hull ());
for (size_t i = 0; i < o.holes (); ++i) {
h = hfunc (o.hole (i).hash (), h);
h = hfunc (o.hole (i), h);
}
return h;
}
@ -191,25 +240,54 @@ namespace DB_HASH_NAMESPACE
/**
* @brief Hash value for a simple polygon
*/
template <>
struct hash <db::SimplePolygon>
template <class C>
struct hash <db::simple_polygon<C> >
{
size_t operator() (const db::SimplePolygon &o) const
size_t operator() (const db::simple_polygon<C> &o) const
{
return o.hull ().hash ();
return hfunc (o.hull ());
}
};
/**
* @brief A hash value for a db::CellInstArray
* @brief Hash value for a simple transformation
*/
template <>
struct hash <db::CellInstArray>
template <class C>
struct hash <db::simple_trans<C> >
{
size_t operator() (const db::CellInstArray &o) const
size_t operator() (const db::simple_trans<C> &t) const
{
return hfunc (int (t.rot ()), hfunc (t.disp ()));
}
};
/**
* @brief Hash value for a complex transformation
*/
template <class I, class F, class R>
struct hash <db::complex_trans<I, F, R> >
{
size_t operator() (const db::complex_trans<I, F, R> &t) const
{
size_t h = hfunc (int64_t (0.5 + t.angle () / db::epsilon));
h = hfunc (int64_t (0.5 + t.mag () / db::epsilon), h);
h = hfunc (int (t.is_mirror ()), h);
h = hfunc (t.disp (), h);
return h;
}
};
/**
* @brief A hash value for a db::CellInstArray and db::DCellInstArray
*/
template <class C>
struct hash <db::array <db::CellInst, db::simple_trans<C> > >
{
size_t operator() (const db::array <db::CellInst, db::simple_trans<C> > &o) const
{
size_t h = hfunc (o.object ().cell_index ());
db::Vector a, b;
db::vector<C> a, b;
unsigned long na = 1, nb = 1;
if (o.is_regular_array (a, b, na, nb)) {
h = hfunc (a, h);
@ -219,15 +297,9 @@ namespace DB_HASH_NAMESPACE
}
if (o.is_complex ()) {
db::ICplxTrans t = o.complex_trans ();
h = hfunc (int (0.5 + t.angle () * 1000000), h);
h = hfunc (int (0.5 + t.mag () * 1000000), h);
h = hfunc (int (t.is_mirror ()), h);
h = hfunc (db::Vector (t.disp ()), h);
h = hfunc (o.complex_trans (), h);
} else {
db::Trans t = o.front ();
h = hfunc (int (t.rot ()), h);
h = hfunc (t.disp (), h);
h = hfunc (o.front (), h);
}
return h;
@ -246,6 +318,25 @@ namespace DB_HASH_NAMESPACE
}
};
/**
* @brief A hash value for a db::LayerProperties object
*/
template <>
struct hash <db::LayerProperties>
{
size_t operator() (const db::LayerProperties &o) const
{
if (o.is_named ()) {
return hfunc (o.name.c_str ());
} else {
size_t h = hfunc (o.layer);
h = hfunc (o.datatype, h);
h = hfunc (o.name.c_str (), h);
return h;
}
}
};
/**
* @brief Generic hash for a pair of objects
*/

View File

@ -338,6 +338,48 @@ public:
return !operator== (b);
}
/**
* @brief A fuzzy operator to establish a sorting order.
*/
bool less (const path<C> &b) const
{
if (! coord_traits::equal (m_width, b.m_width)) {
return m_width < b.m_width;
}
if (! coord_traits::equal (m_bgn_ext, b.m_bgn_ext)) {
return m_bgn_ext < b.m_bgn_ext;
}
if (! coord_traits::equal (m_end_ext, b.m_end_ext)) {
return m_end_ext < b.m_end_ext;
}
return db::less (m_points, b.m_points);
}
/**
* @brief Fuzzy qquality test
*/
bool equal (const path<C> &b) const
{
if (! coord_traits::equal (m_width, b.m_width)) {
return false;
}
if (! coord_traits::equal (m_bgn_ext, b.m_bgn_ext)) {
return false;
}
if (! coord_traits::equal (m_end_ext, b.m_end_ext)) {
return false;
}
return db::equal (m_points, b.m_points);
}
/**
* @brief Fuzzy inequality test
*/
bool not_equal (const path<C> &b) const
{
return !equal (b);
}
/**
* @brief Set the width
*/

View File

@ -30,6 +30,7 @@
#include "dbTypes.h"
#include "tlString.h"
#include "tlTypeTraits.h"
#include "tlVector.h"
#include <string>
@ -274,6 +275,14 @@ public:
*/
bool equal (const point<C> &p) const;
/**
* @brief Fuzzy comparison of points for inequality
*/
bool not_equal (const point<C> &p) const
{
return ! equal (p);
}
/**
* @brief Fuzzy "less" comparison of points
*/
@ -628,6 +637,44 @@ struct point_coord_converter
}
};
/**
* A fuzzy "less" operator for point lists
*/
template <class C>
inline bool less (const tl::vector<point<C> > &a, const tl::vector<point<C> > &b)
{
if (a.size () != b.size ()) {
return a.size () < b.size ();
}
for (typename tl::vector<point<C> >::const_iterator i = a.begin (), j = b.begin (); i != a.end (); ++i, ++j) {
if (! i->equal (*j)) {
return i->less (*j);
}
}
return false;
}
/**
* A fuzzy "equal" operator for point lists
*/
template <class C>
inline bool equal (const tl::vector<point<C> > &a, const tl::vector<point<C> > &b)
{
if (a.size () != b.size ()) {
return false;
}
for (typename tl::vector<point<C> >::const_iterator i = a.begin (), j = b.begin (); i != a.end (); ++i, ++j) {
if (! i->equal (*j)) {
return false;
}
}
return true;
}
}
/**

View File

@ -847,20 +847,6 @@ public:
}
}
/**
* @brief Compute a hash value
*/
size_t hash () const
{
size_t h = ((size_t) mp_points & 3);
point_type *p = (point_type *) ((size_t) mp_points & ~3);
for (size_type i = 0; i < m_size; ++i, ++p) {
h = (h << 4) ^ (h >> 4) ^ size_t (p->x ());
h = (h << 4) ^ (h >> 4) ^ size_t (p->y ());
}
return h;
}
/**
* @brief Compute the bounding box
*
@ -937,7 +923,57 @@ public:
return false;
}
/**
/**
* @brief Fuzzy equality test
*/
bool equal (const polygon_contour<C> &d) const
{
if (size () != d.size ()) {
return false;
}
if (is_hole () != d.is_hole ()) {
return false;
}
simple_iterator p1 = begin (), p2 = d.begin ();
while (p1 != end ()) {
if (! (*p1).equal (*p2)) {
return false;
}
++p1; ++p2;
}
return true;
}
/**
* @brief Fuzzy inequality test
*/
bool not_equal (const polygon_contour<C> &d) const
{
return ! equal (d);
}
/**
* @brief Fuzzy less than-operator
*/
bool less (const polygon_contour<C> &d) const
{
if (size () != d.size ()) {
return size () < d.size ();
}
if (is_hole () != d.is_hole ()) {
return is_hole () < d.is_hole ();
}
simple_iterator p1 = begin (), p2 = d.begin ();
while (p1 != end ()) {
if (! (*p1).equal (*p2)) {
return (*p1).less (*p2);
}
++p1; ++p2;
}
return false;
}
/**
* @brief swap with a different contour
*/
void swap (polygon_contour<C> &d)
@ -1508,6 +1544,75 @@ public:
return !operator== (b);
}
/**
* @brief A fuzzy less operator to establish a sorting order.
*/
bool less (const polygon<C> &b) const
{
// do the simple tests first
if (holes () < b.holes ()) {
return true;
} else if (holes () != b.holes ()) {
return false;
}
if (m_bbox.less (b.m_bbox)) {
return true;
} else if (m_bbox.not_equal (b.m_bbox)) {
return false;
}
// since the list of holes is maintained sorted, we can just
// compare by comparing the holes contours (all must be equal)
typename contour_list_type::const_iterator hh = b.m_ctrs.begin ();
typename contour_list_type::const_iterator h = m_ctrs.begin ();
while (h != m_ctrs.end ()) {
if (h->less (*hh)) {
return true;
} else if (h->not_equal (*hh)) {
return false;
}
++h;
++hh;
}
return false;
}
/**
* @brief Fuzzy equality test
*/
bool equal (const polygon<C> &b) const
{
if (m_bbox.equal (b.m_bbox) && holes () == b.holes ()) {
// since the list of holes is maintained sorted, we can just
// compare by comparing the holes contours (all must be equal)
typename contour_list_type::const_iterator hh = b.m_ctrs.begin ();
typename contour_list_type::const_iterator h = m_ctrs.begin ();
while (h != m_ctrs.end ()) {
if (h->not_equal (*hh)) {
return false;
}
++h;
++hh;
}
return true;
} else {
return false;
}
}
/**
* @brief Fuzzy inequality test
*/
bool not_equal (const polygon<C> &b) const
{
return !equal (b);
}
/**
* @brief Returns true, if the polygon is a simple box
*/
@ -2361,6 +2466,36 @@ public:
return !operator== (b);
}
/**
* @brief A fuzzy less operator to establish a sorting order.
*/
bool less (const simple_polygon<C> &b) const
{
if (m_bbox.less (b.m_bbox)) {
return true;
} else if (m_bbox.not_equal (b.m_bbox)) {
return false;
}
return m_hull.less (b.m_hull);
}
/**
* @brief Fuzzy equality test
*/
bool equal (const simple_polygon<C> &b) const
{
return m_hull.equal (b.m_hull);
}
/**
* @brief Fuzzy inequality test
*/
bool not_equal (const simple_polygon<C> &b) const
{
return ! equal (b);
}
/**
* @brief The hull "begin" point iterator
*

View File

@ -445,49 +445,7 @@ public:
if (m_trans != b.m_trans) {
return m_trans < b.m_trans;
}
// Compare strings or StringRef's by pointer (that is
// the intention of StringRef's: if the text changes, the sort
// order must not!)
if (((size_t) mp_ptr & 1) == 0 || ((size_t) b.mp_ptr & 1) == 0) {
int c = strcmp (string (), b.string ());
if (c != 0) {
return c < 0;
}
} else {
if (mp_ptr != b.mp_ptr) {
// if references are present, use their pointers rather than the strings
// if they belong to the same collection
const StringRef *r1 = reinterpret_cast<const StringRef *> (mp_ptr - 1);
const StringRef *r2 = reinterpret_cast<const StringRef *> (b.mp_ptr - 1);
if (r1->rep () != r2->rep ()) {
int c = strcmp (r1->value ().c_str (), r2->value ().c_str ());
if (c != 0) {
return c < 0;
}
} else {
return mp_ptr < b.mp_ptr;
}
}
}
#if 1
// Compare size and presentation flags - without that, the text repository does not work properly.
if (m_size != b.m_size) {
return m_size < b.m_size;
}
if (m_font != b.m_font) {
return m_font < b.m_font;
}
if (m_halign != b.m_halign) {
return m_halign < b.m_halign;
}
if (m_valign != b.m_valign) {
return m_valign < b.m_valign;
}
#endif
return false;
return text_less (b);
}
/**
@ -499,42 +457,7 @@ public:
if (m_trans != b.m_trans) {
return false;
}
// Compare strings or StringRef's by pointer (that is
// the intention of StringRef's: if the text changes, the sort
// order must not!)
if (((size_t) mp_ptr & 1) == 0 || ((size_t) b.mp_ptr & 1) == 0) {
int c = strcmp (string (), b.string ());
if (c != 0) {
return false;
}
} else {
if (mp_ptr != b.mp_ptr) {
// if references are present, use their pointers rather than the strings
// if they belong to the same collection
const StringRef *r1 = reinterpret_cast<const StringRef *> (mp_ptr - 1);
const StringRef *r2 = reinterpret_cast<const StringRef *> (b.mp_ptr - 1);
if (r1->rep () != r2->rep ()) {
int c = strcmp (r1->value ().c_str (), r2->value ().c_str ());
if (c != 0) {
return false;
}
} else {
return false;
}
}
}
#if 1
// Compare size and presentation flags - without that, the text repository does not work properly.
if (m_size != b.m_size) {
return false;
}
return m_font == b.m_font && m_halign == b.m_halign && m_valign == b.m_valign;
#else
// Don't compare size, font and alignment
return true;
#endif
return text_equal (b);
}
/**
@ -545,6 +468,38 @@ public:
return !operator== (b);
}
/**
* @brief Fuzzy ordering operator
*/
bool less (const text<C> &b) const
{
// Compare transformation
if (m_trans.not_equal (b.m_trans)) {
return m_trans.less (b.m_trans);
}
return text_less (b);
}
/**
* @brief Fuzzy equality test
*/
bool equal (const text<C> &b) const
{
// Compare transformation
if (m_trans.not_equal (b.m_trans)) {
return false;
}
return text_equal (b);
}
/**
* @brief Fuzzy inequality test
*/
bool not_equal (const text<C> &b) const
{
return !equal (b);
}
/**
* @brief The text string write accessor
*/
@ -821,6 +776,91 @@ private:
mp_ptr = new char[s.size() + 1];
strncpy (mp_ptr, s.c_str (), s.size () + 1);
}
bool text_less (const text<C> &b) const
{
// Compare strings or StringRef's by pointer (that is
// the intention of StringRef's: if the text changes, the sort
// order must not!)
if (((size_t) mp_ptr & 1) == 0 || ((size_t) b.mp_ptr & 1) == 0) {
int c = strcmp (string (), b.string ());
if (c != 0) {
return c < 0;
}
} else {
if (mp_ptr != b.mp_ptr) {
// if references are present, use their pointers rather than the strings
// if they belong to the same collection
const StringRef *r1 = reinterpret_cast<const StringRef *> (mp_ptr - 1);
const StringRef *r2 = reinterpret_cast<const StringRef *> (b.mp_ptr - 1);
if (r1->rep () != r2->rep ()) {
int c = strcmp (r1->value ().c_str (), r2->value ().c_str ());
if (c != 0) {
return c < 0;
}
} else {
return mp_ptr < b.mp_ptr;
}
}
}
#if 1
// Compare size and presentation flags - without that, the text repository does not work properly.
if (m_size != b.m_size) {
return m_size < b.m_size;
}
if (m_font != b.m_font) {
return m_font < b.m_font;
}
if (m_halign != b.m_halign) {
return m_halign < b.m_halign;
}
if (m_valign != b.m_valign) {
return m_valign < b.m_valign;
}
#endif
return false;
}
bool text_equal (const text<C> &b) const
{
// Compare strings or StringRef's by pointer (that is
// the intention of StringRef's: if the text changes, the sort
// order must not!)
if (((size_t) mp_ptr & 1) == 0 || ((size_t) b.mp_ptr & 1) == 0) {
int c = strcmp (string (), b.string ());
if (c != 0) {
return false;
}
} else {
if (mp_ptr != b.mp_ptr) {
// if references are present, use their pointers rather than the strings
// if they belong to the same collection
const StringRef *r1 = reinterpret_cast<const StringRef *> (mp_ptr - 1);
const StringRef *r2 = reinterpret_cast<const StringRef *> (b.mp_ptr - 1);
if (r1->rep () != r2->rep ()) {
int c = strcmp (r1->value ().c_str (), r2->value ().c_str ());
if (c != 0) {
return false;
}
} else {
return false;
}
}
}
#if 1
// Compare size and presentation flags - without that, the text repository does not work properly.
if (m_size != b.m_size) {
return false;
}
return m_font == b.m_font && m_halign == b.m_halign && m_valign == b.m_valign;
#else
// Don't compare size, font and alignment
return true;
#endif
}
};
/**

View File

@ -200,6 +200,14 @@ struct unit_trans
return true;
}
/**
* @brief A (fuzzy) inequality test
*/
bool not_equal (const unit_trans &t) const
{
return ! equal (t);
}
/**
* @brief (dummy) inequality
*/
@ -614,6 +622,14 @@ public:
return m_f == t.m_f;
}
/**
* @brief A (dummy) fuzzy inequality test
*/
bool not_equal (const fixpoint_trans &t) const
{
return ! equal (t);
}
/**
* @brief String conversion
*/
@ -930,6 +946,14 @@ public:
return m_u.equal (t.m_u);
}
/**
* @brief A fuzzy inequality test
*/
bool not_equal (const disp_trans<C> &t) const
{
return ! equal (t);
}
/**
* @brief String conversion
*/
@ -1319,7 +1343,7 @@ public:
return !operator== (t);
}
/*
/**
* @brief A fuzzy equality test
*/
bool equal (const simple_trans<C> &t) const
@ -1327,6 +1351,14 @@ public:
return fixpoint_trans<C>::operator== (t) && m_u.equal (t.m_u);
}
/**
* @brief A fuzzy inequality test
*/
bool not_equal (const simple_trans<C> &t) const
{
return ! equal (t);
}
/**
* @brief String conversion
*/
@ -2077,6 +2109,14 @@ public:
fabs (m_mag - t.m_mag) <= eps_f ();
}
/**
* @brief A (fuzzy) inequality test
*/
bool not_equal (const complex_trans &t) const
{
return ! equal (t);
}
/**
* @brief Default string conversion
*/

View File

@ -225,12 +225,20 @@ public:
void set_y (C _y);
/**
* @brief Fuzzy comparison of points
* @brief Fuzzy comparison of vectors
*/
bool equal (const vector<C> &p) const;
/**
* @brief Fuzzy "less" comparison of points
* @brief Fuzzy comparison of vectors for inequality
*/
bool not_equal (const vector<C> &p) const
{
return !equal (p);
}
/**
* @brief Fuzzy "less" comparison of vectors
*/
bool less (const vector<C> &p) const;

View File

@ -24,6 +24,7 @@
#include "gsiDecl.h"
#include "dbPoint.h"
#include "dbBox.h"
#include "dbHash.h"
namespace gsi
{
@ -95,6 +96,11 @@ struct box_defs
return box->moved (vector_type (x, y));
}
static size_t hash_value (const C *box)
{
return std_ext::hfunc (*box);
}
static gsi::Methods methods ()
{
return
@ -408,7 +414,7 @@ struct box_defs
"@return The enlarged box.\n"
) +
method ("transformed", &C::template transformed<simple_trans_type>,
"@brief Transform the box with the given simple transformation\n"
"@brief Transforms the box with the given simple transformation\n"
"\n"
"@args t\n"
"\n"
@ -416,27 +422,33 @@ struct box_defs
"@return The transformed box\n"
) +
method ("transformed", &C::template transformed<complex_trans_type>,
"@brief Transform the box with the given complex transformation\n"
"@brief Transforms the box with the given complex transformation\n"
"\n"
"@args t\n"
"\n"
"@param t The magnifying transformation to apply\n"
"@return The transformed box (a DBox now)\n"
) +
method ("<", &C::operator<,
method ("<", &C::less,
"@brief Less operator\n"
"@args box\n"
"Return true, if this box is 'less' with respect to first and second point (in this order)"
"Returns true, if this box is 'less' with respect to first and second point (in this order)"
) +
method ("==", &C::operator==,
method ("==", &C::equal,
"@brief Equality\n"
"@args box\n"
"Return true, if this box and the given box are equal "
"Returns true, if this box and the given box are equal "
) +
method ("!=", &C::operator!=,
method ("!=", &C::not_equal,
"@brief Inequality\n"
"@args box\n"
"Return true, if this box and the given box are not equal "
"Returns true, if this box and the given box are not equal "
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given box. This method enables boxes as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
constructor ("from_s", &from_string,
"@brief Creates an object from a string\n"

View File

@ -37,6 +37,7 @@
#include "dbPCellDeclaration.h"
#include "dbSaveLayoutOptions.h"
#include "dbWriter.h"
#include "dbHash.h"
#include "tlStream.h"
namespace gsi
@ -342,6 +343,102 @@ struct cell_inst_array_defs
return ComplexTransIterator (c);
}
static size_t hash_value (const C *i)
{
return std_ext::hfunc (*i);
}
static bool less (const C *i, const C &other)
{
if (i->object ().cell_index () != other.object ().cell_index ()) {
return i->object ().cell_index () < other.object ().cell_index ();
}
db::vector<coord_type> a, b;
unsigned long na = 1, nb = 1;
bool r = i->is_regular_array (a, b, na, nb);
db::vector<coord_type> aother, bother;
unsigned long naother = 1, nbother = 1;
bool rother = other.is_regular_array (aother, bother, naother, nbother);
if (r != rother) {
return r < rother;
} else if (r) {
if (a.not_equal (aother)) {
return a.less (aother);
}
if (b.not_equal (bother)) {
return b.less (bother);
}
if (na != naother) {
return na < naother;
}
if (nb != nbother) {
return nb < nbother;
}
}
bool c = i->is_complex ();
bool cother = other.is_complex ();
if (c != cother) {
return c < cother;
} else if (c) {
return i->complex_trans ().less (other.complex_trans ());
} else {
return i->front ().less (other.front ());
}
}
static bool equal (const C *i, const C &other)
{
if (i->object ().cell_index () != other.object ().cell_index ()) {
return false;
}
db::vector<coord_type> a, b;
unsigned long na = 1, nb = 1;
bool r = i->is_regular_array (a, b, na, nb);
db::vector<coord_type> aother, bother;
unsigned long naother = 1, nbother = 1;
bool rother = other.is_regular_array (aother, bother, naother, nbother);
if (r != rother) {
return false;
} else if (r) {
if (a.not_equal (aother)) {
return false;
}
if (b.not_equal (bother)) {
return false;
}
if (na != naother) {
return false;
}
if (nb != nbother) {
return false;
}
}
bool c = i->is_complex ();
bool cother = other.is_complex ();
if (c != cother) {
return false;
} else if (c) {
return i->complex_trans ().equal (other.complex_trans ());
} else {
return i->front ().equal (other.front ());
}
}
static bool not_equal (const C *i, const C &other)
{
return ! equal (i, other);
}
static gsi::Methods methods (bool new_doc)
{
return
@ -484,21 +581,27 @@ struct cell_inst_array_defs
"This method has been introduced in version 0.20.\n"
)
) +
gsi::method ("<", &C::operator<,
gsi::method_ext ("<", &less,
"@brief Compares two arrays for 'less'\n"
"@args other\n"
"The comparison provides an arbitrary sorting criterion and not specific sorting order. It "
"is guaranteed that if an array a is less than b, b is not less than a. In addition, it a "
"is not less than b and b is not less than a, then a is equal to b."
) +
gsi::method ("==", &C::operator==,
gsi::method_ext ("==", &equal,
"@brief Compares two arrays for equality\n"
"@args other"
) +
gsi::method ("!=", &C::operator!=,
gsi::method_ext ("!=", &not_equal,
"@brief Compares two arrays for inequality\n"
"@args other"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given cell instance. This method enables cell instances as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
gsi::method ("is_complex?", &C::is_complex,
"@brief Gets a value indicating whether the array is a complex array\n"
"\n"

View File

@ -24,6 +24,7 @@
#include "gsiDecl.h"
#include "dbPoint.h"
#include "dbEdge.h"
#include "dbHash.h"
namespace gsi
{
@ -131,6 +132,11 @@ struct edge_defs
return edge->sq_length ();
}
static size_t hash_value (const C *e)
{
return std_ext::hfunc (*e);
}
static gsi::Methods methods ()
{
return
@ -151,22 +157,28 @@ struct edge_defs
"\n"
"Two points are given to create a new edge."
) +
method ("<", &C::operator<,
method ("<", &C::less,
"@brief Less operator\n"
"@args e\n"
"@param e The object to compare against\n"
"@return True, if the edge is 'less' as the other edge with respect to first and second point"
) +
method ("==", &C::operator==,
method ("==", &C::equal,
"@brief Equality test\n"
"@args e\n"
"@param e The object to compare against"
) +
method ("!=", &C::operator!=,
method ("!=", &C::not_equal,
"@brief Inequality test\n"
"@args e\n"
"@param e The object to compare against"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given edge. This method enables edges as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method ("moved", &C::moved,
"@brief Returns the moved edge (does not modify self)\n"
"@args p\n"

View File

@ -24,6 +24,7 @@
#include "gsiDecl.h"
#include "dbEdgePair.h"
#include "dbHash.h"
namespace gsi
{
@ -58,6 +59,11 @@ struct edge_pair_defs
return new C (first, second);
}
static size_t hash_value (const C *ep)
{
return std_ext::hfunc (*ep);
}
static gsi::Methods methods ()
{
return
@ -133,6 +139,33 @@ struct edge_pair_defs
method ("bbox", &C::bbox,
"@brief Gets the bounding box of the edge pair\n"
) +
method ("<", &C::less,
"@brief Less operator\n"
"@args box\n"
"Returns true, if this edge pair is 'less' with respect to first and second edge\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method ("==", &C::equal,
"@brief Equality\n"
"@args box\n"
"Returns true, if this edge pair and the given one are equal\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method ("!=", &C::not_equal,
"@brief Inequality\n"
"@args box\n"
"Returns true, if this edge pair and the given one are not equal\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given edge pair. This method enables edge pairs as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method ("transformed", &C::template transformed<simple_trans_type>,
"@brief Returns the transformed pair\n"
"@args t\n"

View File

@ -31,6 +31,7 @@
#include "dbLibrary.h"
#include "dbLibraryManager.h"
#include "dbPCellDeclaration.h"
#include "dbHash.h"
#include "tlStream.h"
namespace gsi
@ -111,6 +112,12 @@ db::LayerProperties li_from_string (const char *s)
return lp;
}
static
size_t hash_value (const db::LayerProperties *l)
{
return std_ext::hfunc (*l);
}
// since there already exists a "LayerProperties" object, we call this one "LayerInfo"
Class<db::LayerProperties> decl_LayerInfo ("LayerInfo",
gsi::constructor ("new", &ctor_layer_info_default,
@ -164,14 +171,14 @@ Class<db::LayerProperties> decl_LayerInfo ("LayerInfo",
"This method was added in version 0.18.\n"
) +
gsi::method ("==", &db::LayerProperties::operator==,
"@brief Compare two layer info objects\n"
"@brief Compares two layer info objects\n"
"@return True, if both are equal\n"
"@args b\n"
"\n"
"This method was added in version 0.18.\n"
) +
gsi::method ("!=", &db::LayerProperties::operator!=,
"@brief Compare two layer info objects\n"
"@brief Compares two layer info objects\n"
"@return True, if both are not equal\n"
"@args b\n"
"\n"
@ -187,7 +194,13 @@ Class<db::LayerProperties> decl_LayerInfo ("LayerInfo",
"\n"
"This method was added in version 0.18.\n"
) +
gsi::method ("anonymous?", &db::LayerProperties::is_null,
gsi::method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given layer info object. This method enables layer info objects as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
gsi::method ("anonymous?", &db::LayerProperties::is_null,
"@brief Returns true, if the layer has no specification (i.e. is created by the default constructor).\n"
"@return True, if the layer does not have any specification.\n"
"\n"

View File

@ -24,6 +24,7 @@
#include "gsiDecl.h"
#include "dbPoint.h"
#include "dbPath.h"
#include "dbHash.h"
namespace gsi
{
@ -107,6 +108,11 @@ struct path_defs
return C (p->transformed (icomplex_trans_type (s)));
}
static size_t hash_value (const C *e)
{
return std_ext::hfunc (*e);
}
static gsi::Methods methods ()
{
return
@ -142,22 +148,28 @@ struct path_defs
"@param end_ext The end extension of the path\n"
"@param round If this flag is true, the path will get rounded ends\n"
) +
method ("<", &C::operator<,
method ("<", &C::less,
"@brief Less operator\n"
"@args p\n"
"@param p The object to compare against\n"
"This operator is provided to establish some, not necessarily a certain sorting order"
) +
method ("==", &C::operator==,
method ("==", &C::equal,
"@brief Equality test\n"
"@args p\n"
"@param p The object to compare against"
) +
method ("!=", &C::operator!=,
method ("!=", &C::not_equal,
"@brief Inequality test\n"
"@args p\n"
"@param p The object to compare against\n"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given polygon. This method enables polygons as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method_ext ("points=", &set_points,
"@brief Set the points of the path\n"
"@args p\n"

View File

@ -24,6 +24,7 @@
#include "gsiDecl.h"
#include "dbPoint.h"
#include "dbBox.h"
#include "dbHash.h"
namespace gsi
{
@ -74,6 +75,11 @@ struct point_defs
return -*p;
}
static size_t hash_value (const C *pt)
{
return std_ext::hfunc (*pt);
}
static gsi::Methods methods ()
{
return
@ -123,7 +129,7 @@ struct point_defs
"\n"
"Starting with version 0.25, this method renders a vector."
) +
method ("<", &C::operator<,
method ("<", &C::less,
"@brief \"less\" comparison operator\n"
"\n"
"@args p\n"
@ -131,16 +137,22 @@ struct point_defs
"This operator is provided to establish a sorting\n"
"order\n"
) +
method ("==", &C::operator==,
method ("==", &C::equal,
"@brief Equality test operator\n"
"\n"
"@args p\n"
) +
method ("!=", &C::operator!=,
method ("!=", &C::not_equal,
"@brief Inequality test operator\n"
"\n"
"@args p\n"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given point. This method enables points as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method ("x", &C::x,
"@brief Accessor to the x coordinate\n"
) +

View File

@ -26,6 +26,7 @@
#include "dbPolygon.h"
#include "dbPolygonTools.h"
#include "dbPolygonGenerators.h"
#include "dbHash.h"
namespace gsi
{
@ -204,6 +205,11 @@ struct simple_polygon_defs
return res;
}
static size_t hash_value (const C *p)
{
return std_ext::hfunc (*p);
}
static gsi::Methods methods ()
{
return
@ -244,17 +250,31 @@ struct simple_polygon_defs
"\n"
"This method has been introduced in version 0.23.\n"
) +
method ("==", &C::operator==,
method ("<", &C::less,
"@brief Less operator\n"
"@args p\n"
"@param p The object to compare against\n"
"This operator is provided to establish some, not necessarily a certain sorting order\n"
"\n"
"This method has been introduced in version 0.25."
) +
method ("==", &C::equal,
"@brief Equality test\n"
"@args p\n"
"@param p The object to compare against\n"
) +
method ("!=", &C::operator!=,
method ("!=", &C::not_equal,
"@brief Inequality test\n"
"@args p\n"
"@param p The object to compare against\n"
) +
method_ext ("points=", &set_points1,
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given polygon. This method enables polygons as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method_ext ("points=", &set_points1,
"@brief Set the points of the simple polygon\n"
"\n"
"@args pts\n"
@ -950,6 +970,11 @@ struct polygon_defs
return db::compute_rounded (*p, rinner, router, n);
}
static size_t hash_value (const C *p)
{
return std_ext::hfunc (*p);
}
static gsi::Methods methods ()
{
return
@ -987,22 +1012,28 @@ struct polygon_defs
"\n"
"This method has been introduced in version 0.23.\n"
) +
method ("<", &C::operator<,
method ("<", &C::less,
"@brief Less operator\n"
"@args p\n"
"@param p The object to compare against\n"
"This operator is provided to establish some, not necessarily a certain sorting order\n"
) +
method ("==", &C::operator==,
method ("==", &C::equal,
"@brief Equality test\n"
"@args p\n"
"@param p The object to compare against\n"
) +
method ("!=", &C::operator!=,
method ("!=", &C::not_equal,
"@brief Inequality test\n"
"@args p\n"
"@param p The object to compare against\n"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given polygon. This method enables polygons as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method_ext ("hull=", &set_hull1,
"@brief Set the points of the hull of polygon\n"
"@args p\n"

View File

@ -24,6 +24,7 @@
#include "gsiDecl.h"
#include "dbPoint.h"
#include "dbText.h"
#include "dbHash.h"
namespace gsi
{
@ -142,6 +143,11 @@ struct text_defs
return *c;
}
static size_t hash_value (const C *box)
{
return std_ext::hfunc (*box);
}
static gsi::Methods methods ()
{
return
@ -327,26 +333,32 @@ struct text_defs
"@param t The magnifying transformation to apply\n"
"@return The transformed text (a DText now)\n"
) +
method ("<", &C::operator<,
method ("<", &C::less,
"@brief Less operator\n"
"@args t\n"
"@param t The object to compare against\n"
"This operator is provided to establish some, not necessarily a certain sorting order"
) +
method ("==", &C::operator==,
method ("==", &C::equal,
"@brief Equality\n"
"\n"
"@args text\n"
"\n"
"Return true, if this text object and the given text are equal "
) +
method ("!=", &C::operator!=,
method ("!=", &C::not_equal,
"@brief Inequality\n"
"\n"
"@args text\n"
"\n"
"Return true, if this text object and the given text are not equal "
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given text object. This method enables texts as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
constructor ("from_s", &from_string,
"@brief Creates an object from a string\n"
"@args s\n"

View File

@ -28,6 +28,7 @@
#include "dbPolygon.h"
#include "dbPath.h"
#include "dbText.h"
#include "dbHash.h"
namespace gsi
{
@ -135,6 +136,11 @@ struct trans_defs
return text.transformed (*t);
}
static size_t hash_value (const C *t)
{
return std_ext::hfunc (*t);
}
static gsi::Methods methods ()
{
return
@ -304,17 +310,23 @@ struct trans_defs
"@param t The transformation to apply before\n"
"@return The modified transformation\n"
) +
method ("<", &C::operator<, arg ("other"),
method ("<", &C::less, arg ("other"),
"@brief Provides a 'less' criterion for sorting\n"
"This method is provided to implement a sorting order. The definition of 'less' is opaque and might change in "
"future versions."
) +
method ("==", &C::operator==, arg ("other"),
method ("==", &C::equal, arg ("other"),
"@brief Tests for equality\n"
) +
method ("!=", &C::operator!=, arg ("other"),
method ("!=", &C::not_equal, arg ("other"),
"@brief Tests for inequality\n"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given transformation. This method enables transformations as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
constructor ("from_s", &from_string, arg ("s"),
"@brief Creates a transformation from a string\n"
"Creates the object from a string representation (as returned by \\to_s)\n"
@ -622,6 +634,11 @@ struct cplx_trans_defs
return text.transformed (*t);
}
static size_t hash_value (const C *t)
{
return std_ext::hfunc (*t);
}
static gsi::Methods methods ()
{
return
@ -813,17 +830,23 @@ struct cplx_trans_defs
"@param t The transformation to apply before\n"
"@return The modified transformation\n"
) +
method ("<", &C::operator<, arg ("other"),
method ("<", &C::less, arg ("other"),
"@brief Provides a 'less' criterion for sorting\n"
"This method is provided to implement a sorting order. The definition of 'less' is opaque and might change in "
"future versions."
) +
method ("==", &C::operator==, arg ("other"),
method ("==", &C::equal, arg ("other"),
"@brief Tests for equality\n"
) +
method ("!=", &C::operator!=, arg ("other"),
method ("!=", &C::not_equal, arg ("other"),
"@brief Tests for inequality\n"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given transformation. This method enables transformations as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
constructor ("from_s", &from_string, arg ("s"),
"@brief Creates an object from a string\n"
"Creates the object from a string representation (as returned by \\to_s)\n"

View File

@ -24,6 +24,7 @@
#include "gsiDecl.h"
#include "dbVector.h"
#include "dbPoint.h"
#include "dbHash.h"
namespace gsi
{
@ -94,6 +95,11 @@ struct vector_defs
return db::sprod_sign (*p, q);
}
static size_t hash_value (const C *v)
{
return std_ext::hfunc (*v);
}
static gsi::Methods methods ()
{
return
@ -137,7 +143,7 @@ struct vector_defs
"\n"
"Subtract vector v from self by subtracting the coordinates.\n"
) +
method ("<", &C::operator<,
method ("<", &C::less,
"@brief \"less\" comparison operator\n"
"\n"
"@args v\n"
@ -145,16 +151,22 @@ struct vector_defs
"This operator is provided to establish a sorting\n"
"order\n"
) +
method ("==", &C::operator==,
method ("==", &C::equal,
"@brief Equality test operator\n"
"\n"
"@args v\n"
) +
method ("!=", &C::operator!=,
method ("!=", &C::not_equal,
"@brief Inequality test operator\n"
"\n"
"@args v\n"
) +
method_ext ("hash", &hash_value,
"@brief Computes a hash value\n"
"Returns a hash value for the given vector. This method enables vectors as hash keys.\n"
"\n"
"This method has been introduced in version 0.25.\n"
) +
method ("x", &C::x,
"@brief Accessor to the x coordinate\n"
) +

View File

@ -1619,12 +1619,14 @@ rba_init (RubyInterpreterPrivateData *d)
rb_define_alias (klass, (mt->name (mid) + "=").c_str (), mt->name (mid).c_str ());
}
if (mt->name (mid) == "to_s") {
#if HAVE_RUBY_VERSION_CODE>=20000
// Ruby 2.x does no longer alias "inspect" to "to_s" automatically, so we have to do this:
if (mt->name (mid) == "to_s") {
rb_define_alias (klass, "inspect", "to_s");
}
#endif
} else if (mt->name (mid) == "==") {
rb_define_alias (klass, "eql?", "==");
}
}

View File

@ -115,6 +115,7 @@ RUBYTEST (dbSimplePolygonTest, "dbSimplePolygonTest.rb")
RUBYTEST (dbTextTest, "dbTextTest.rb")
RUBYTEST (dbTilingProcessorTest, "dbTilingProcessorTest.rb")
RUBYTEST (dbTransTest, "dbTransTest.rb")
RUBYTEST (dbVectorTest, "dbVectorTest.rb")
RUBYTEST (edtTest, "edtTest.rb")
RUBYTEST (extNetTracer, "extNetTracer.rb")
RUBYTEST (imgObject, "imgObject.rb")

View File

@ -3,9 +3,6 @@ verbose(true)
source(File.dirname(__FILE__) + "/drctest.gds", "TOPTOP")
big_tests = false # @@@ set to true to enable all tests
0.1.um.to_s == "0.1" || raise("unexpected value")
0.1.micron.to_s == "0.1" || raise("unexpected value")

View File

@ -392,6 +392,46 @@ class DBBox_TestClass < TestBase
end
# Fuzzy compare
def test_7_Box
b1 = RBA::DBox::new(1, 2, 3, 4)
b2 = RBA::DBox::new(1 + 1e-7, 2, 3, 4)
b3 = RBA::DBox::new(1 + 1e-4, 2, 3, 4)
assert_equal(b1.to_s, "(1,2;3,4)")
assert_equal(b2.to_s, "(1.0000001,2;3,4)")
assert_equal(b3.to_s, "(1.0001,2;3,4)")
assert_equal(b1 == b2, true)
assert_equal(b1.eql?(b2), true)
assert_equal(b1 != b2, false)
assert_equal(b1 < b2, false)
assert_equal(b2 < b1, false)
assert_equal(b1 == b3, false)
assert_equal(b1.eql?(b3), false)
assert_equal(b1 != b3, true)
assert_equal(b1 < b3, true)
assert_equal(b3 < b1, false)
end
# Hash values
def test_8_Box
b1 = RBA::DBox::new(1, 2, 3, 4)
b2 = RBA::DBox::new(1 + 1e-7, 2, 3, 4)
b3 = RBA::DBox::new(1 + 1e-4, 2, 3, 4)
assert_equal(b1.hash == b2.hash, true)
assert_equal(b1.hash == b3.hash, false)
h = { b1 => "a", b3 => "b" }
assert_equal(h[b1], "a")
assert_equal(h[b2], "a")
assert_equal(h[b3], "b")
end
end
load("test_epilogue.rb")

View File

@ -61,9 +61,9 @@ class DBCellInst_TestClass < TestBase
assert_equal(at.trans.to_s, "r90 0,0")
assert_equal(at.cplx_trans.to_s, "r135 *1 0,0")
assert_equal(at < a, false)
assert_equal(at < a, true)
assert_equal(at < atdup, false)
assert_equal(a < at, true)
assert_equal(a < at, false)
assert_equal(atdup < at, false)
assert_equal(a != at, true)
assert_equal(a == at, false)
@ -123,9 +123,9 @@ class DBCellInst_TestClass < TestBase
assert_equal(at.cplx_trans.to_s, "r135 *1 0,0")
assert_equal(at.to_s, "#0 r135 *1 0,0 [-20,10*3;-40,30*5]")
assert_equal(at < a, false)
assert_equal(at < a, true)
assert_equal(at < atdup, false)
assert_equal(a < at, true)
assert_equal(a < at, false)
assert_equal(atdup < at, false)
assert_equal(a != at, true)
assert_equal(a == at, false)
@ -190,9 +190,9 @@ class DBCellInst_TestClass < TestBase
assert_equal(at.trans.to_s, "r90 0,0")
assert_equal(at.cplx_trans.to_s, "r135 *1 0,0")
assert_equal(at < a, false)
assert_equal(at < a, true)
assert_equal(at < atdup, false)
assert_equal(a < at, true)
assert_equal(a < at, false)
assert_equal(atdup < at, false)
assert_equal(a != at, true)
assert_equal(a == at, false)
@ -252,9 +252,9 @@ class DBCellInst_TestClass < TestBase
assert_equal(at.cplx_trans.to_s, "r135 *1 0,0")
assert_equal(at.to_s, "#0 r135 *1 0,0 [-20,10*3;-40,30*5]")
assert_equal(at < a, false)
assert_equal(at < a, true)
assert_equal(at < atdup, false)
assert_equal(a < at, true)
assert_equal(a < at, false)
assert_equal(atdup < at, false)
assert_equal(a != at, true)
assert_equal(a == at, false)
@ -419,6 +419,134 @@ class DBCellInst_TestClass < TestBase
end
# DCellInstArray fuzzy compare
def test_2_FuzzyCompare
i1 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)))
i2 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5 + 1e-7, 2.5)))
i3 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5 + 1e-4, 2.5)))
assert_equal(i1 == i2, true)
assert_equal(i1 != i2, false)
assert_equal(i1.eql?(i2), true)
assert_equal(i1 < i2, false)
assert_equal(i2 < i1, false)
assert_equal(i1 == i3, false)
assert_equal(i1 != i3, true)
assert_equal(i1.eql?(i3), false)
assert_equal(i1 < i3, true)
assert_equal(i3 < i1, false)
end
# DCellInstArray hash function
def test_2_Hash
i1 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)))
i2 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5 + 1e-7, 2.5)))
i3 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5 + 1e-4, 2.5)))
i4 = RBA::DCellInstArray.new(3, RBA::DTrans.new(RBA::DPoint.new(1.5 + 1e-4, 2.5)))
assert_equal(i1.hash == i2.hash, true)
assert_equal(i1.hash == i3.hash, false)
assert_equal(i1.hash == i4.hash, false)
h = { i1 => "i1", i3 => "i3", i4 => "i4" }
assert_equal(h[i1], "i1")
assert_equal(h[i2], "i1")
assert_equal(h[i3], "i3")
assert_equal(h[i4], "i4")
end
# DCellInstArray hash function
def test_3_Hash
i1 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3, 4), 5, 6)
i2 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1 + 1e-7, 2), RBA::DPoint::new(3, 4), 5, 6)
i3 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1 + 1e-4, 2), RBA::DPoint::new(3, 4), 5, 6)
i4 = RBA::DCellInstArray.new(3, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3, 4), 7, 6)
assert_equal(i1.hash == i2.hash, true)
assert_equal(i1.hash == i3.hash, false)
assert_equal(i1.hash == i4.hash, false)
h = { i1 => "i1", i3 => "i3", i4 => "i4" }
assert_equal(h[i1], "i1")
assert_equal(h[i2], "i1")
assert_equal(h[i3], "i3")
assert_equal(h[i4], "i4")
end
# DCellInstArray fuzzy compare
def test_3_FuzzyCompare
i1 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3, 4), 5, 6)
i2 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1 + 1e-7, 2), RBA::DPoint::new(3, 4), 5, 6)
i3 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1 + 1e-4, 2), RBA::DPoint::new(3, 4), 5, 6)
assert_equal(i1 == i2, true)
assert_equal(i1 != i2, false)
assert_equal(i1.eql?(i2), true)
assert_equal(i1 < i2, false)
assert_equal(i2 < i1, false)
assert_equal(i1 == i3, false)
assert_equal(i1 != i3, true)
assert_equal(i1.eql?(i3), false)
assert_equal(i1 < i3, true)
assert_equal(i3 < i1, false)
end
# DCellInstArray hash function
def test_4_Hash
i1 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3, 4), 5, 6)
i2 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3 + 1e-7, 4), 5, 6)
i3 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3 + 1e-4, 4), 5, 6)
i4 = RBA::DCellInstArray.new(3, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3, 4), 5, 8)
i5 = RBA::DCellInstArray.new(3, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)))
assert_equal(i1.hash == i2.hash, true)
assert_equal(i1.hash == i3.hash, false)
assert_equal(i1.hash == i4.hash, false)
h = { i1 => "i1", i3 => "i3", i4 => "i4", i5 => "i5" }
assert_equal(h[i1], "i1")
assert_equal(h[i2], "i1")
assert_equal(h[i3], "i3")
assert_equal(h[i4], "i4")
assert_equal(h[i5], "i5")
end
# DCellInstArray fuzzy compare
def test_4_FuzzyCompare
i1 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3, 4), 5, 6)
i2 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3 + 1e-7, 4), 5, 6)
i3 = RBA::DCellInstArray.new(7, RBA::DTrans.new(RBA::DPoint.new(1.5, 2.5)), RBA::DPoint::new(1, 2), RBA::DPoint::new(3 + 1e-4, 4), 5, 6)
assert_equal(i1 == i2, true)
assert_equal(i1 != i2, false)
assert_equal(i1.eql?(i2), true)
assert_equal(i1 < i2, false)
assert_equal(i2 < i1, false)
assert_equal(i1 == i3, false)
assert_equal(i1 != i3, true)
assert_equal(i1.eql?(i3), false)
assert_equal(i1 < i3, true)
assert_equal(i3 < i1, false)
end
end
load("test_epilogue.rb")

View File

@ -71,6 +71,75 @@ class DBEdgePair_TestClass < TestBase
end
# Fuzzy compare
def test_3
b1 = RBA::DEdgePair::new(RBA::DEdge::new(1, 2, 3, 4), RBA::DEdge::new(11, 12, 13, 14))
b2a = RBA::DEdgePair::new(RBA::DEdge::new(1 + 1e-7, 2, 3, 4), RBA::DEdge::new(11, 12, 13, 14))
b2b = RBA::DEdgePair::new(RBA::DEdge::new(1, 2, 3, 4), RBA::DEdge::new(11 + 1e-7, 12, 13, 14))
b3a = RBA::DEdgePair::new(RBA::DEdge::new(1 + 1e-4, 2, 3, 4), RBA::DEdge::new(11, 12, 13, 14))
b3b = RBA::DEdgePair::new(RBA::DEdge::new(1, 2, 3, 4), RBA::DEdge::new(11 + 1e-4, 12, 13, 14))
assert_equal(b1.to_s, "(1,2;3,4)/(11,12;13,14)")
assert_equal(b2a.to_s, "(1.0000001,2;3,4)/(11,12;13,14)")
assert_equal(b2b.to_s, "(1,2;3,4)/(11.0000001,12;13,14)")
assert_equal(b3a.to_s, "(1.0001,2;3,4)/(11,12;13,14)")
assert_equal(b3b.to_s, "(1,2;3,4)/(11.0001,12;13,14)")
assert_equal(b1 == b2a, true)
assert_equal(b1.eql?(b2a), true)
assert_equal(b1 != b2a, false)
assert_equal(b1 < b2a, false)
assert_equal(b2a < b1, false)
assert_equal(b1 == b2b, true)
assert_equal(b1.eql?(b2b), true)
assert_equal(b1 != b2b, false)
assert_equal(b1 < b2b, false)
assert_equal(b2b < b1, false)
assert_equal(b2a == b2b, true)
assert_equal(b2a.eql?(b2b), true)
assert_equal(b2a != b2b, false)
assert_equal(b2a < b2b, false)
assert_equal(b2b < b2a, false)
assert_equal(b1 == b3a, false)
assert_equal(b1 == b3b, false)
assert_equal(b1.eql?(b3a), false)
assert_equal(b1.eql?(b3b), false)
assert_equal(b1 != b3a, true)
assert_equal(b1 != b3b, true)
assert_equal(b1 < b3a, true)
assert_equal(b1 < b3b, true)
assert_equal(b3a < b1, false)
assert_equal(b3b < b1, false)
assert_equal(b3b < b3a, true)
assert_equal(b3a < b3b, false)
end
# Hash values
def test_4
b1 = RBA::DEdgePair::new(RBA::DEdge::new(1, 2, 3, 4), RBA::DEdge::new(11, 12, 13, 14))
b2a = RBA::DEdgePair::new(RBA::DEdge::new(1 + 1e-7, 2, 3, 4), RBA::DEdge::new(11, 12, 13, 14))
b2b = RBA::DEdgePair::new(RBA::DEdge::new(1, 2, 3, 4), RBA::DEdge::new(11 + 1e-7, 12, 13, 14))
b3a = RBA::DEdgePair::new(RBA::DEdge::new(1 + 1e-4, 2, 3, 4), RBA::DEdge::new(11, 12, 13, 14))
b3b = RBA::DEdgePair::new(RBA::DEdge::new(1, 2, 3, 4), RBA::DEdge::new(11 + 1e-4, 12, 13, 14))
assert_equal(b1.hash == b2a.hash, true)
assert_equal(b1.hash == b2b.hash, true)
assert_equal(b1.hash == b3a.hash, false)
assert_equal(b1.hash == b3b.hash, false)
assert_equal(b3a.hash == b3b.hash, false)
h = { b1 => "a", b3a => "b", b3b => "c" }
assert_equal(h[b1], "a")
assert_equal(h[b2a], "a")
assert_equal(h[b2b], "a")
assert_equal(h[b3a], "b")
assert_equal(h[b3b], "c")
end
end
load("test_epilogue.rb")

View File

@ -224,6 +224,46 @@ class DBEdge_TestClass < TestBase
end
# Fuzzy compare
def test_2_Edge
b1 = RBA::DEdge::new(1, 2, 3, 4)
b2 = RBA::DEdge::new(1 + 1e-7, 2, 3, 4)
b3 = RBA::DEdge::new(1 + 1e-4, 2, 3, 4)
assert_equal(b1.to_s, "(1,2;3,4)")
assert_equal(b2.to_s, "(1.0000001,2;3,4)")
assert_equal(b3.to_s, "(1.0001,2;3,4)")
assert_equal(b1 == b2, true)
assert_equal(b1.eql?(b2), true)
assert_equal(b1 != b2, false)
assert_equal(b1 < b2, false)
assert_equal(b2 < b1, false)
assert_equal(b1 == b3, false)
assert_equal(b1.eql?(b3), false)
assert_equal(b1 != b3, true)
assert_equal(b1 < b3, true)
assert_equal(b3 < b1, false)
end
# Hash values
def test_3_Edge
b1 = RBA::DEdge::new(1, 2, 3, 4)
b2 = RBA::DEdge::new(1 + 1e-7, 2, 3, 4)
b3 = RBA::DEdge::new(1 + 1e-4, 2, 3, 4)
assert_equal(b1.hash == b2.hash, true)
assert_equal(b1.hash == b3.hash, false)
h = { b1 => "a", b3 => "b" }
assert_equal(h[b1], "a")
assert_equal(h[b2], "a")
assert_equal(h[b3], "b")
end
end
load("test_epilogue.rb")

View File

@ -1985,6 +1985,30 @@ END
end
# LayerInfo hash values
def test_19
l1 = RBA::LayerInfo::new("a")
l1c = RBA::LayerInfo::new("a")
l2 = RBA::LayerInfo::new(1, 2, "a")
l3 = RBA::LayerInfo::new(1, 2)
assert_equal(l1.eql?(l2), false)
assert_equal(l1.eql?(l3), false)
assert_equal(l2.eql?(l3), false)
assert_equal(l1.eql?(l1c), true)
assert_equal(l1.hash == l2.hash, false)
assert_equal(l1.hash == l3.hash, false)
assert_equal(l2.hash == l3.hash, false)
h = { l1 => "a", l2 => "b", l3 => "c" }
assert_equal(h[l1], "a")
assert_equal(h[l2], "b")
assert_equal(h[l3], "c")
end
end
load("test_epilogue.rb")

View File

@ -190,6 +190,120 @@ class DBPath_TestClass < TestBase
end
# Fuzzy compare
def test_3_Path
p1 = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
p2a = RBA::DPath::new([ RBA::DPoint::new(1e-7, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
p2b = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500 + 1e-7, -500, 1500)
p2c = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500 + 1e-7, 1500)
p2d = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500 + 1e-7)
p3a = RBA::DPath::new([ RBA::DPoint::new(1e-4, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
p3b = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500 + 1e-4, -500, 1500)
p3c = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500 + 1e-4, 1500)
p3d = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500 + 1e-4)
p4a = RBA::DPath::new([ RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
p4b = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1500, 2000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
assert_equal(p1 == p2a, true)
assert_equal(p1 == p2b, true)
assert_equal(p1 == p2c, true)
assert_equal(p1 == p2d, true)
assert_equal(p1.eql?(p2a), true)
assert_equal(p1.eql?(p2b), true)
assert_equal(p1.eql?(p2c), true)
assert_equal(p1.eql?(p2d), true)
assert_equal(p1 != p2a, false)
assert_equal(p1 != p2b, false)
assert_equal(p1 != p2c, false)
assert_equal(p1 != p2d, false)
assert_equal(p1 < p2a, false)
assert_equal(p1 < p2b, false)
assert_equal(p1 < p2c, false)
assert_equal(p1 < p2d, false)
assert_equal(p2a < p1, false)
assert_equal(p2b < p1, false)
assert_equal(p2c < p1, false)
assert_equal(p2d < p1, false)
assert_equal(p1 == p3a, false)
assert_equal(p1 == p3b, false)
assert_equal(p1 == p3c, false)
assert_equal(p1 == p3d, false)
assert_equal(p3a == p3b, false)
assert_equal(p3a == p3c, false)
assert_equal(p3a == p3d, false)
assert_equal(p3b == p3c, false)
assert_equal(p3b == p3d, false)
assert_equal(p3c == p3d, false)
assert_equal(p1.eql?(p3a), false)
assert_equal(p1.eql?(p3b), false)
assert_equal(p1.eql?(p3c), false)
assert_equal(p1.eql?(p3d), false)
assert_equal(p1 != p3a, true)
assert_equal(p1 != p3b, true)
assert_equal(p1 != p3c, true)
assert_equal(p1 != p3d, true)
assert_equal(p1 < p3a, true)
assert_equal(p1 < p3b, true)
assert_equal(p1 < p3c, true)
assert_equal(p1 < p3d, true)
assert_equal(p3a < p1, false)
assert_equal(p3b < p1, false)
assert_equal(p3c < p1, false)
assert_equal(p3d < p1, false)
assert_equal(p1 == p4a, false)
assert_equal(p1 == p4b, false)
assert_equal(p1.eql?(p4a), false)
assert_equal(p1.eql?(p4b), false)
assert_equal(p1 != p4a, true)
assert_equal(p1 != p4b, true)
assert_equal(p1 < p4a, false)
assert_equal(p1 < p4b, true)
assert_equal(p4a < p1, true)
assert_equal(p4b < p1, false)
end
# Hash values
def test_4_Path
p1 = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
p2a = RBA::DPath::new([ RBA::DPoint::new(1e-7, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
p2b = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500 + 1e-7, -500, 1500)
p2c = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500 + 1e-7, 1500)
p2d = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500 + 1e-7)
p3a = RBA::DPath::new([ RBA::DPoint::new(1e-4, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
p3b = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500 + 1e-4, -500, 1500)
p3c = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500 + 1e-4, 1500)
p3d = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500 + 1e-4)
p4a = RBA::DPath::new([ RBA::DPoint::new(0, 1000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
p4b = RBA::DPath::new([ RBA::DPoint::new(0, 0),RBA::DPoint::new(0, 1000), RBA::DPoint::new(1500, 2000), RBA::DPoint::new(1000, 5000) ], 2500, -500, 1500)
assert_equal(p1.hash == p2a.hash, true)
assert_equal(p1.hash == p2b.hash, true)
assert_equal(p1.hash == p2c.hash, true)
assert_equal(p1.hash == p2d.hash, true)
assert_equal(p1.hash == p3a.hash, false)
assert_equal(p1.hash == p3b.hash, false)
assert_equal(p1.hash == p3c.hash, false)
assert_equal(p1.hash == p3d.hash, false)
assert_equal(p1.hash == p4a.hash, false)
assert_equal(p1.hash == p4b.hash, false)
h = { p1 => "p1", p3a => "p3a", p3b => "p3b", p3c => "p3c", p3d => "p3d", p4a => "p4a", p4b => "p4b" }
assert_equal(h[p1], "p1")
assert_equal(h[p3a], "p3a")
assert_equal(h[p3b], "p3b")
assert_equal(h[p3c], "p3c")
assert_equal(h[p3d], "p3d")
assert_equal(h[p4a], "p4a")
assert_equal(h[p4b], "p4b")
end
end
load("test_epilogue.rb")

View File

@ -103,6 +103,46 @@ class DBPoint_TestClass < TestBase
end
# Fuzzy compare
def test_3_Point
p1 = RBA::DPoint::new(1, 2)
p2 = RBA::DPoint::new(1 + 1e-7, 2)
p3 = RBA::DPoint::new(1 + 1e-4, 2)
assert_equal(p1.to_s, "1,2")
assert_equal(p2.to_s, "1.0000001,2")
assert_equal(p3.to_s, "1.0001,2")
assert_equal(p1 == p2, true)
assert_equal(p1.eql?(p2), true)
assert_equal(p1 != p2, false)
assert_equal(p1 < p2, false)
assert_equal(p2 < p1, false)
assert_equal(p1 == p3, false)
assert_equal(p1.eql?(p3), false)
assert_equal(p1 != p3, true)
assert_equal(p1 < p3, true)
assert_equal(p3 < p1, false)
end
# Hash values
def test_4_Point
p1 = RBA::DPoint::new(1, 2)
p2 = RBA::DPoint::new(1 + 1e-7, 2)
p3 = RBA::DPoint::new(1 + 1e-4, 2)
assert_equal(p1.hash == p2.hash, true)
assert_equal(p1.hash == p3.hash, false)
h = { p1 => "a", p3 => "b" }
assert_equal(h[p1], "a")
assert_equal(h[p2], "a")
assert_equal(h[p3], "b")
end
end
load("test_epilogue.rb")

View File

@ -525,6 +525,115 @@ class DBPolygon_TestClass < TestBase
end
# fuzzy compare
def test_FuzzyCompare
p1 = RBA::DPolygon::from_s("(0,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p2a = RBA::DPolygon::from_s("(0.0000001,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p2b = RBA::DPolygon::from_s("(0,0;0,40;40,40;40,0/10.0000001,10;30,10;30,30;10,30)")
p3a = RBA::DPolygon::from_s("(0.0001,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p3b = RBA::DPolygon::from_s("(0,0;0,40;40,40;40,0/10.0001,10;30,10;30,30;10,30)")
p4a = RBA::DPolygon::from_s("(0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p4b = RBA::DPolygon::from_s("(0,0;1,1;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p4c = RBA::DPolygon::from_s("(0,0;0,40;40,40;40,0)")
p4d = RBA::DPolygon::from_s("(0,0;1,1;0,40;40,40;40,0/10,10;30,10;30,30;10,30/15,15;16,15;16,16;15,16)")
assert_equal(p1 == p2a, true)
assert_equal(p1 == p2b, true)
assert_equal(p1 == p3a, false)
assert_equal(p1 == p3b, false)
assert_equal(p1 == p4a, false)
assert_equal(p1 == p4b, false)
assert_equal(p1 == p4c, false)
assert_equal(p1 == p4d, false)
assert_equal(p1.eql?(p2a), true)
assert_equal(p1.eql?(p2b), true)
assert_equal(p1.eql?(p3a), false)
assert_equal(p1.eql?(p3b), false)
assert_equal(p3a.eql?(p3b), false)
assert_equal(p1.eql?(p4a), false)
assert_equal(p1.eql?(p4b), false)
assert_equal(p1.eql?(p4c), false)
assert_equal(p1.eql?(p4d), false)
assert_equal(p4a.eql?(p4b), false)
assert_equal(p4a.eql?(p4c), false)
assert_equal(p4a.eql?(p4d), false)
assert_equal(p4b.eql?(p4c), false)
assert_equal(p4b.eql?(p4d), false)
assert_equal(p4c.eql?(p4d), false)
assert_equal(p1 < p2a, false)
assert_equal(p1 < p2b, false)
assert_equal(p1 < p3a, true)
assert_equal(p1 < p3b, true)
assert_equal(p1 < p4a, false)
assert_equal(p1 < p4b, true)
assert_equal(p1 < p4c, false)
assert_equal(p1 < p4d, true)
assert_equal(p4a < p4b, true)
assert_equal(p4a < p4c, false)
assert_equal(p4a < p4d, true)
assert_equal(p4b < p4c, false)
assert_equal(p4b < p4d, true)
assert_equal(p4c < p4d, true)
assert_equal(p2a < p1, false)
assert_equal(p2b < p1, false)
assert_equal(p3a < p1, false)
assert_equal(p3b < p1, false)
assert_equal(p4a < p1, true)
assert_equal(p4b < p1, false)
assert_equal(p4c < p1, true)
assert_equal(p4d < p1, false)
assert_equal(p4b < p4a, false)
assert_equal(p4c < p4a, true)
assert_equal(p4d < p4a, false)
assert_equal(p4c < p4b, true)
assert_equal(p4d < p4b, false)
assert_equal(p4d < p4c, false)
end
# hash values
def test_HashValues
p1 = RBA::DPolygon::from_s("(0,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p2a = RBA::DPolygon::from_s("(0.0000001,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p2b = RBA::DPolygon::from_s("(0,0;0,40;40,40;40,0/10.0000001,10;30,10;30,30;10,30)")
p3a = RBA::DPolygon::from_s("(0.0001,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p3b = RBA::DPolygon::from_s("(0,0;0,40;40,40;40,0/10.0001,10;30,10;30,30;10,30)")
p4a = RBA::DPolygon::from_s("(0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p4b = RBA::DPolygon::from_s("(0,0;1,1;0,40;40,40;40,0/10,10;30,10;30,30;10,30)")
p4c = RBA::DPolygon::from_s("(0,0;0,40;40,40;40,0)")
p4d = RBA::DPolygon::from_s("(0,0;1,1;0,40;40,40;40,0/10,10;30,10;30,30;10,30/15,15;16,15;16,16;15,16)")
assert_equal(p1.hash == p2a.hash, true)
assert_equal(p1.hash == p2b.hash, true)
assert_equal(p1.hash == p3a.hash, false)
assert_equal(p1.hash == p3b.hash, false)
assert_equal(p1.hash == p4a.hash, false)
assert_equal(p1.hash == p4b.hash, false)
assert_equal(p1.hash == p4c.hash, false)
assert_equal(p1.hash == p4d.hash, false)
assert_equal(p4a.hash == p4b.hash, false)
assert_equal(p4a.hash == p4c.hash, false)
assert_equal(p4a.hash == p4d.hash, false)
assert_equal(p4b.hash == p4c.hash, false)
assert_equal(p4b.hash == p4d.hash, false)
assert_equal(p4c.hash == p4d.hash, false)
h = { p1 => "p1", p3a => "p3a", p3b => "p3b", p4a => "p4a", p4b => "p4b", p4c => "p4c", p4d => "p4d" }
assert_equal(h[p1], "p1")
assert_equal(h[p2a], "p1")
assert_equal(h[p2b], "p1")
assert_equal(h[p3a], "p3a")
assert_equal(h[p3b], "p3b")
assert_equal(h[p4a], "p4a")
assert_equal(h[p4b], "p4b")
assert_equal(h[p4c], "p4c")
assert_equal(h[p4d], "p4d")
end
end
load("test_epilogue.rb")

View File

@ -304,6 +304,61 @@ class DBSimplePolygon_TestClass < TestBase
end
# fuzzy compare
def test_FuzzyCompare
p1 = RBA::DSimplePolygon::from_s("(0,0;0,40;40,40;40,0)")
p2a = RBA::DSimplePolygon::from_s("(0.0000001,0;0,40;40,40;40,0)")
p3a = RBA::DSimplePolygon::from_s("(0.0001,0;0,40;40,40;40,0)")
p4a = RBA::DSimplePolygon::from_s("(0,40;40,40;40,0)")
p4b = RBA::DSimplePolygon::from_s("(0,0;1,1;0,40;40,40;40,0)")
assert_equal(p1 == p2a, true)
assert_equal(p1 == p3a, false)
assert_equal(p1 == p4a, false)
assert_equal(p1 == p4b, false)
assert_equal(p1.eql?(p2a), true)
assert_equal(p1.eql?(p3a), false)
assert_equal(p1.eql?(p4a), false)
assert_equal(p1.eql?(p4b), false)
assert_equal(p4a.eql?(p4b), false)
assert_equal(p1 < p2a, false)
assert_equal(p1 < p3a, true)
assert_equal(p1 < p4a, false)
assert_equal(p1 < p4b, true)
assert_equal(p4a < p4b, true)
assert_equal(p2a < p1, false)
assert_equal(p3a < p1, false)
assert_equal(p4a < p1, true)
assert_equal(p4b < p1, false)
assert_equal(p4b < p4a, false)
end
# hash values
def test_HashValues
p1 = RBA::DSimplePolygon::from_s("(0,0;0,40;40,40;40,0)")
p2a = RBA::DSimplePolygon::from_s("(0.0000001,0;0,40;40,40;40,0)")
p3a = RBA::DSimplePolygon::from_s("(0.0001,0;0,40;40,40;40,0)")
p4a = RBA::DSimplePolygon::from_s("(0,40;40,40;40,0)")
p4b = RBA::DSimplePolygon::from_s("(0,0;1,1;0,40;40,40;40,0)")
assert_equal(p1.hash == p2a.hash, true)
assert_equal(p1.hash == p3a.hash, false)
assert_equal(p1.hash == p4a.hash, false)
assert_equal(p1.hash == p4b.hash, false)
assert_equal(p4a.hash == p4b.hash, false)
h = { p1 => "p1", p3a => "p3a", p4a => "p4a", p4b => "p4b" }
assert_equal(h[p1], "p1")
assert_equal(h[p3a], "p3a")
assert_equal(h[p4a], "p4a")
assert_equal(h[p4b], "p4b")
end
end
load("test_epilogue.rb")

View File

@ -140,6 +140,51 @@ class DBText_TestClass < TestBase
end
# Fuzzy compare
def test_2_Text
a1 = RBA::DText::new( "hallo", 10.0, -15.0 )
a2 = RBA::DText::new( "hallo", 10.0 + 1e-7, -15.0 )
a3 = RBA::DText::new( "hallo", 10.0 + 1e-4, -15.0 )
a4 = RBA::DText::new( "hllo", 10.0, -15.0 )
assert_equal(a1 == a2, true)
assert_equal(a1 != a2, false)
assert_equal(a1.eql?(a2), true)
assert_equal(a1 < a2, false)
assert_equal(a2 < a1, false)
assert_equal(a1 == a3, false)
assert_equal(a1 != a3, true)
assert_equal(a1.eql?(a3), false)
assert_equal(a1 < a3, true)
assert_equal(a3 < a1, false)
assert_equal(a1 == a4, false)
assert_equal(a1 != a4, true)
assert_equal(a1.eql?(a4), false)
assert_equal(a1 < a4, true)
assert_equal(a4 < a1, false)
end
# Hash function
def test_3_Text
a1 = RBA::DText::new( "hallo", 10.0, -15.0 )
a2 = RBA::DText::new( "hallo", 10.0 + 1e-7, -15.0 )
a3 = RBA::DText::new( "hallo", 10.0 + 1e-4, -15.0 )
a4 = RBA::DText::new( "hllo", 10.0, -15.0 )
h = { a1 => "a1", a3 => "a3", a4 => "a4" }
assert_equal(h[a1], "a1")
assert_equal(h[a2], "a1")
assert_equal(h[a3], "a3")
assert_equal(h[a4], "a4")
end
end
load("test_epilogue.rb")

View File

@ -372,6 +372,179 @@ class DBTrans_TestClass < TestBase
end
# Fuzzy compare
def test_5_Trans_FuzzyCompare
t1 = RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ))
t2 = RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17 + 1e-7, 5 ))
t3 = RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17 + 1e-4, 5 ))
t4a = RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 18, 5 ))
t4b = RBA::DTrans::new( RBA::DTrans::R90, RBA::DPoint::new( 18, 5 ))
assert_equal(t1 == t2, true)
assert_equal(t1.eql?(t2), true)
assert_equal(t1 != t2, false)
assert_equal(t1 < t2, false)
assert_equal(t2 < t1, false)
assert_equal(t1 == t3, false)
assert_equal(t1.eql?(t3), false)
assert_equal(t1 != t3, true)
assert_equal(t1 < t3, true)
assert_equal(t3 < t1, false)
assert_equal(t1 == t4a, false)
assert_equal(t1.eql?(t4a), false)
assert_equal(t1 != t4a, true)
assert_equal(t1 < t4a, true)
assert_equal(t4a < t1, false)
assert_equal(t1 == t4b, false)
assert_equal(t1.eql?(t4b), false)
assert_equal(t1 != t4b, true)
assert_equal(t1 < t4b, false)
assert_equal(t4b < t1, true)
end
# Complex trans fuzzy compare
def test_5_CplxTrans_FuzzyCompare
t1 = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0)
t2a = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17 + 1e-7, 5 ) ), 1.0)
t2b = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0 + 1e-11)
t2c = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0)
t2c.angle = t2c.angle + 1e-11
t3a = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17 + 1e-4, 5 ) ), 1.0)
t3b = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0 + 1e-4)
t3c = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0)
t3c.angle = t3c.angle + 1e-4
t4 = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::R90, RBA::DPoint::new( 18, 5 ) ), 1.0)
assert_equal(t1 == t2a, true)
assert_equal(t1.eql?(t2a), true)
assert_equal(t1 != t2a, false)
assert_equal(t1 < t2a, false)
assert_equal(t2a < t1, false)
assert_equal(t1 == t2b, true)
assert_equal(t1.eql?(t2b), true)
assert_equal(t1 != t2b, false)
assert_equal(t1 < t2b, false)
assert_equal(t2b < t1, false)
assert_equal(t1 == t2c, true)
assert_equal(t1.eql?(t2c), true)
assert_equal(t1 != t2c, false)
assert_equal(t1 < t2c, false)
assert_equal(t2c < t1, false)
assert_equal(t1 == t3a, false)
assert_equal(t1.eql?(t3a), false)
assert_equal(t1 != t3a, true)
assert_equal(t1 < t3a, true)
assert_equal(t3a < t1, false)
assert_equal(t1 == t3b, false)
assert_equal(t1.eql?(t3b), false)
assert_equal(t1 != t3b, true)
assert_equal(t1 < t3b, false)
assert_equal(t3b < t1, true)
assert_equal(t1 == t3c, false)
assert_equal(t1.eql?(t3c), false)
assert_equal(t1 != t3c, true)
assert_equal(t1 < t3c, true)
assert_equal(t3c < t1, false)
assert_equal(t3a == t3b, false)
assert_equal(t3a.eql?(t3b), false)
assert_equal(t3a != t3b, true)
assert_equal(t3a < t3b, false)
assert_equal(t3b < t3a, true)
assert_equal(t3a == t3c, false)
assert_equal(t3a.eql?(t3c), false)
assert_equal(t3a != t3c, true)
assert_equal(t3a < t3c, false)
assert_equal(t3c < t3a, true)
assert_equal(t3b == t3c, false)
assert_equal(t3b.eql?(t3c), false)
assert_equal(t3b != t3c, true)
assert_equal(t3b < t3c, true)
assert_equal(t3c < t3b, false)
assert_equal(t1 == t4, false)
assert_equal(t1.eql?(t4), false)
assert_equal(t1 != t4, true)
assert_equal(t1 < t4, true)
assert_equal(t4 < t1, false)
end
# Hash values
def test_5_Trans_Hash
t1 = RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ))
t2 = RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17 + 1e-7, 5 ))
t3 = RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17 + 1e-4, 5 ))
t4a = RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 18, 5 ))
t4b = RBA::DTrans::new( RBA::DTrans::R90, RBA::DPoint::new( 18, 5 ))
assert_equal(t1.hash == t2.hash, true)
assert_equal(t1.hash == t3.hash, false)
assert_equal(t1.hash == t4a.hash, false)
assert_equal(t1.hash == t4b.hash, false)
h = { t1 => "t1", t3 => "t3", t4a => "t4a", t4b => "t4b" }
assert_equal(h[t1], "t1")
assert_equal(h[t2], "t1")
assert_equal(h[t3], "t3")
assert_equal(h[t4a], "t4a")
assert_equal(h[t4b], "t4b")
end
# Complex trans hash values
def test_5_CplxTrans_Hash
t1 = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0)
t2a = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17 + 1e-7, 5 ) ), 1.0)
t2b = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0 + 1e-11)
t2c = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0)
t2c.angle = t2c.angle + 1e-11
t3a = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17 + 1e-4, 5 ) ), 1.0)
t3b = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0 + 1e-4)
t3c = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::M135, RBA::DPoint::new( 17, 5 ) ), 1.0)
t3c.angle = t3c.angle + 1e-4
t4 = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::R90, RBA::DPoint::new( 18, 5 ) ), 1.0)
assert_equal(t1.hash == t2a.hash, true)
assert_equal(t1.hash == t2b.hash, true)
assert_equal(t1.hash == t2c.hash, true)
assert_equal(t1.hash == t3a.hash, false)
assert_equal(t1.hash == t3b.hash, false)
assert_equal(t1.hash == t3c.hash, false)
assert_equal(t3a.hash == t3b.hash, false)
assert_equal(t3a.hash == t3c.hash, false)
assert_equal(t3b.hash == t3c.hash, false)
assert_equal(t1.hash == t4.hash, false)
h = { t1 => "t1", t3a => "t3a", t3b => "t3b", t3c => "t3c", t4 => "t4" }
assert_equal(h[t1], "t1")
assert_equal(h[t2a], "t1")
assert_equal(h[t2b], "t1")
assert_equal(h[t2c], "t1")
assert_equal(h[t3a], "t3a")
assert_equal(h[t3b], "t3b")
assert_equal(h[t3c], "t3c")
assert_equal(h[t4], "t4")
end
end
load("test_epilogue.rb")

143
testdata/ruby/dbVectorTest.rb vendored Normal file
View File

@ -0,0 +1,143 @@
$:.push(File::dirname($0))
load("test_prologue.rb")
class DBVector_TestClass < TestBase
# DVector basics
def test_1_DVector
a = RBA::DVector::new( 1, -17 )
b = RBA::DVector::new
c = RBA::DVector::new( RBA::Vector::new( 5, 11 ) )
assert_equal( a.to_s, "1,-17" )
assert_equal( RBA::DVector::from_s(a.to_s).to_s, a.to_s )
assert_equal( (-a).to_s, "-1,17" )
assert_equal( b.to_s, "0,0" )
assert_equal( c.to_s, "5,11" )
assert_equal( (a + c).to_s, "6,-6" )
assert_equal( (a * 0.5).to_s, "0.5,-8.5" )
assert_equal( (a - c).to_s, "-4,-28" )
assert_equal( a == c, false )
assert_equal( a == a, true )
assert_equal( a != c, true )
assert_equal( a != a, false )
assert_equal( a.x.to_s, "1.0" )
assert_equal( a.y.to_s, "-17.0" )
assert_equal( (a.length - Math::sqrt(17 * 17 + 1 * 1)).abs < 1e-12, true )
b.x = a.x
b.y = a.y
assert_equal( a, b )
end
# Transforming DVector
def test_2_DVector
a = RBA::DVector::new( 1, -17 )
b = RBA::DVector::new
t = RBA::DTrans::new( RBA::DTrans::R90, RBA::DVector::new( 5, -2 ))
assert_equal( t.trans(a).to_s, "17,1" )
m = RBA::DCplxTrans::new( RBA::DTrans::new( RBA::DTrans::R90, RBA::DVector::new( 5, -2 )), 0.5 )
assert_equal( m.trans(a).to_s, "8.5,0.5" )
end
# Vector basics
def test_1_Vector
a = RBA::Vector::new( 1, -17 )
b = RBA::Vector::new
c = RBA::Vector::new( RBA::DVector::new( 5, 11 ) )
assert_equal( a.to_s, "1,-17" )
assert_equal( RBA::Vector::from_s(a.to_s).to_s, a.to_s )
assert_equal( (-a).to_s, "-1,17" )
assert_equal( b.to_s, "0,0" )
assert_equal( c.to_s, "5,11" )
assert_equal( (a + c).to_s, "6,-6" )
assert_equal( (a * 0.5).to_s, "1,-9" )
assert_equal( (a - c).to_s, "-4,-28" )
assert_equal( a == c, false )
assert_equal( a == a, true )
assert_equal( a != c, true )
assert_equal( a != a, false )
assert_equal( a.x.to_s, "1" )
assert_equal( a.y.to_s, "-17" )
assert_equal( (a.length - Math::sqrt(17 * 17 + 1 * 1)).abs < 1e-12, true )
b.x = a.x
b.y = a.y
assert_equal( a, b )
end
# Transforming Vector
def test_2_Vector
a = RBA::Vector::new( 1, -17 )
b = RBA::Vector::new
t = RBA::Trans::new( RBA::Trans::R90, RBA::Vector::new( 5, -2 ))
assert_equal( t.trans(a).to_s, "17,1" )
m = RBA::CplxTrans::new( RBA::Trans::new( RBA::Trans::R90, RBA::Vector::new( 5, -2 )), 0.5 )
assert_equal( m.trans(a).to_s, "8.5,0.5" )
end
# Fuzzy compare
def test_3_Vector
p1 = RBA::DVector::new(1, 2)
p2 = RBA::DVector::new(1 + 1e-7, 2)
p3 = RBA::DVector::new(1 + 1e-4, 2)
assert_equal(p1.to_s, "1,2")
assert_equal(p2.to_s, "1.0000001,2")
assert_equal(p3.to_s, "1.0001,2")
assert_equal(p1 == p2, true)
assert_equal(p1.eql?(p2), true)
assert_equal(p1 != p2, false)
assert_equal(p1 < p2, false)
assert_equal(p2 < p1, false)
assert_equal(p1 == p3, false)
assert_equal(p1.eql?(p3), false)
assert_equal(p1 != p3, true)
assert_equal(p1 < p3, true)
assert_equal(p3 < p1, false)
end
# Hash values
def test_4_Vector
p1 = RBA::DVector::new(1, 2)
p2 = RBA::DVector::new(1 + 1e-7, 2)
p3 = RBA::DVector::new(1 + 1e-4, 2)
assert_equal(p1.hash == p2.hash, true)
assert_equal(p1.hash == p3.hash, false)
h = { p1 => "a", p3 => "b" }
assert_equal(h[p1], "a")
assert_equal(h[p2], "a")
assert_equal(h[p3], "b")
end
end
load("test_epilogue.rb")