@@ -408,6 +408,26 @@ struct Node {
408408 ));
409409 }
410410
411+ /* * Compare two miniscript subtrees, using a non-recursive algorithm. */
412+ friend int Compare (const Node<Key>& node1, const Node<Key>& node2)
413+ {
414+ std::vector<std::pair<const Node<Key>&, const Node<Key>&>> queue;
415+ queue.emplace_back (node1, node2);
416+ while (!queue.empty ()) {
417+ const auto & [a, b] = queue.back ();
418+ queue.pop_back ();
419+ if (std::tie (a.fragment , a.k , a.keys , a.data ) < std::tie (b.fragment , b.k , b.keys , b.data )) return -1 ;
420+ if (std::tie (b.fragment , b.k , b.keys , b.data ) < std::tie (a.fragment , a.k , a.keys , a.data )) return 1 ;
421+ if (a.subs .size () < b.subs .size ()) return -1 ;
422+ if (b.subs .size () < a.subs .size ()) return 1 ;
423+ size_t n = a.subs .size ();
424+ for (size_t i = 0 ; i < n; ++i) {
425+ queue.emplace_back (*a.subs [n - 1 - i], *b.subs [n - 1 - i]);
426+ }
427+ }
428+ return 0 ;
429+ }
430+
411431 // ! Compute the type for this miniscript.
412432 Type CalcType () const {
413433 using namespace internal ;
@@ -765,20 +785,7 @@ struct Node {
765785 bool IsSaneTopLevel () const { return IsValidTopLevel () && IsSane () && NeedsSignature (); }
766786
767787 // ! Equality testing.
768- bool operator ==(const Node<Key>& arg) const
769- {
770- if (fragment != arg.fragment ) return false ;
771- if (k != arg.k ) return false ;
772- if (data != arg.data ) return false ;
773- if (keys != arg.keys ) return false ;
774- if (subs.size () != arg.subs .size ()) return false ;
775- for (size_t i = 0 ; i < subs.size (); ++i) {
776- if (!(*subs[i] == *arg.subs [i])) return false ;
777- }
778- assert (scriptlen == arg.scriptlen );
779- assert (typ == arg.typ );
780- return true ;
781- }
788+ bool operator ==(const Node<Key>& arg) const { return Compare (*this , arg) == 0 ; }
782789
783790 // Constructors with various argument combinations.
784791 Node (Fragment nt, std::vector<NodeRef<Key>> sub, std::vector<unsigned char > arg, uint32_t val = 0 ) : fragment(nt), k(val), data(std::move(arg)), subs(std::move(sub)), ops(CalcOps()), ss(CalcStackSize()), typ(CalcType()), scriptlen(CalcScriptLen()) {}
0 commit comments