|
|
@@ -1,1104 +0,0 @@
|
|
|
-// Filename: setTransitionHelpers.I
|
|
|
-// Created by: drose (25Jan99)
|
|
|
-//
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-
|
|
|
-#include "nodeTransitionCacheEntry.h"
|
|
|
-#include "config_graph.h"
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_get_interest
|
|
|
-// Description: Returns the NodeTransition elements of interest to
|
|
|
-// us. These are the elements of the first sequence--a
|
|
|
-// NodeTransition map--whose keys appear in the second
|
|
|
-// sequence, a sorted list of NodeTransition
|
|
|
-// TypeHandles.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_get_interest(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < *first2) {
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if (*first2 < (*first1).first) {
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_override_union
|
|
|
-// Description: Accepts two NodeTransition or NodeAttribute maps, and
|
|
|
-// builds a new map which is the union of the first two.
|
|
|
-// If an element appears in both maps, the entry from
|
|
|
-// the second is preferred.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_override_union(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- *result = *first2;
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_merge_union
|
|
|
-// Description: Accepts two NodeAttribute maps, and builds a new map
|
|
|
-// which is the union of the first two. If an element
|
|
|
-// appears in both maps, the two are merged, preferring
|
|
|
-// the second.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_merge_union(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- PT(NodeAttribute) c = (*first1).second->merge((*first2).second);
|
|
|
- *result = pair<TypeHandle, PT(NodeAttribute) >((*first1).first, c);
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_arc_union
|
|
|
-// Description: As above, but updates the transitions on the way to
|
|
|
-// indicate they are being attached to (or removed from)
|
|
|
-// the indicated arc.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_arc_union(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- NodeRelation *to_arc, OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- (*first2).second->added_to_arc(to_arc);
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- (*first1).second->removed_from_arc(to_arc);
|
|
|
- (*first2).second->added_to_arc(to_arc);
|
|
|
- *result = *first2;
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- (*first2).second->added_to_arc(to_arc);
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_arc_compose
|
|
|
-// Description:
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_arc_compose(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- NodeRelation *to_arc, OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- (*first2).second->added_to_arc(to_arc);
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- (*first1).second->removed_from_arc(to_arc);
|
|
|
-
|
|
|
- PT(NodeTransition) c = (*first1).second->compose((*first2).second);
|
|
|
- if (c != (NodeTransition *)NULL) {
|
|
|
- c->added_to_arc(to_arc);
|
|
|
- *result = pair<TypeHandle, PT(NodeTransition) >((*first1).first, c);
|
|
|
- ++result;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- (*first2).second->added_to_arc(to_arc);
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_arc_compose
|
|
|
-// Description:
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_arc_compose(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- NodeTransition *c = (*first1).second->compose((*first2).second);
|
|
|
- if (c != (NodeTransition *)NULL) {
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first, c);
|
|
|
- ++result;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_compose
|
|
|
-// Description: Accepts two NodeTransition maps, and builds a new
|
|
|
-// list (a NodeTransition map) which represents the
|
|
|
-// memberwise composition of the two input maps.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_compose(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::compose((*first1).second, (*first2).second));
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_invert_compose
|
|
|
-// Description: Accepts two NodeTransition maps, and builds a new
|
|
|
-// list (a NodeTransition map) which represents the
|
|
|
-// memberwise result of invert_compose of the two input
|
|
|
-// maps.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_invert_compose(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first, NodeTransitionCacheEntry::invert((*first1).second));
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- NodeTransitionCacheEntry ic =
|
|
|
- NodeTransitionCacheEntry::invert_compose((*first1).second,
|
|
|
- (*first2).second);
|
|
|
- if (!ic.is_identity()) {
|
|
|
- // Only bother to store the result if it's not identity.
|
|
|
- *result = pair<TypeHandle, PT(NodeTransition) >((*first1).first, ic);
|
|
|
- ++result;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first, NodeTransitionCacheEntry::invert((*first1).second));
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- *result = *first2;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-// This macro is used in the various cached_compose functions to
|
|
|
-// possibly output debug statements about which pieces we're
|
|
|
-// composing.
|
|
|
-
|
|
|
-#ifndef NDEBUG
|
|
|
-#define OUTPUT_CC_ELEM(desc, type) \
|
|
|
-{ \
|
|
|
- if (wrt_cat.is_spam()) { \
|
|
|
- wrt_cat.spam() << "in " << desc << ": " << (type) << "\n"; \
|
|
|
- } \
|
|
|
-}
|
|
|
-#else
|
|
|
-#define OUTPUT_CC_ELEM(desc, type)
|
|
|
-#endif
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_cached_compose_not_1
|
|
|
-// Description: One of several support functions for
|
|
|
-// tmap_cached_compose(), below, this handles the case
|
|
|
-// of tmap_cached_compose() for a NodeTransition that
|
|
|
-// is already known not to be present in list 1, but may
|
|
|
-// be in one or both of lists 2 and 3.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator2, class InputIterator3, class OutputIterator>
|
|
|
-void
|
|
|
-tmap_cached_compose_not_1(InputIterator2 &first2, InputIterator3 &first3,
|
|
|
- UpdateSeq now, OutputIterator &result) {
|
|
|
- if ((*first2).first < (*first3).first) {
|
|
|
- // Here's an element in list 2 that is not in lists 1 or 3.
|
|
|
- OUTPUT_CC_ELEM("2", (*first2).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first2).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- (NodeTransitionCacheEntry(),
|
|
|
- (*first2).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- now));
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
-
|
|
|
- } else if ((*first3).first < (*first2).first) {
|
|
|
- // Here's an element in list 3 that is not lists 2 or 1.
|
|
|
- OUTPUT_CC_ELEM("3", (*first3).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first3).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- (NodeTransitionCacheEntry(),
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- (*first3).second,
|
|
|
- now));
|
|
|
- ++first3;
|
|
|
- ++result;
|
|
|
-
|
|
|
- } else { // (*first2).first == (*first3).first
|
|
|
- // Here's an element in lists 2 and 3 that is not in list 1.
|
|
|
- OUTPUT_CC_ELEM("2, 3", (*first2).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first2).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- (NodeTransitionCacheEntry(),
|
|
|
- (*first2).second,
|
|
|
- (*first3).second,
|
|
|
- now));
|
|
|
- ++first2;
|
|
|
- ++first3;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_cached_compose_not_2
|
|
|
-// Description: One of several support functions for
|
|
|
-// tmap_cached_compose(), below, this handles the case
|
|
|
-// of tmap_cached_compose() for an NodeTransition that
|
|
|
-// is already known not to be present in list 2, but may
|
|
|
-// be in one or both of lists 1 and 3.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator3, class OutputIterator>
|
|
|
-void
|
|
|
-tmap_cached_compose_not_2(InputIterator1 &first1, InputIterator3 &first3,
|
|
|
- UpdateSeq now, OutputIterator &result) {
|
|
|
- if ((*first1).first < (*first3).first) {
|
|
|
- // Here's an element in list 1 that is not in lists 2 or 3.
|
|
|
- OUTPUT_CC_ELEM("1", (*first1).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- ((*first1).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- now));
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
-
|
|
|
- } else if ((*first3).first < (*first1).first) {
|
|
|
- // Here's an element in list 3 that is not lists 1 or 2.
|
|
|
- OUTPUT_CC_ELEM("3", (*first3).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first3).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- (NodeTransitionCacheEntry(),
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- (*first3).second,
|
|
|
- now));
|
|
|
- ++first3;
|
|
|
- ++result;
|
|
|
-
|
|
|
- } else { // (*first1).first == (*first3).first
|
|
|
- // Here's an element in lists 1 and 3 that is not in list 2.
|
|
|
- OUTPUT_CC_ELEM("1, 3", (*first1).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- ((*first1).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- (*first3).second,
|
|
|
- now));
|
|
|
- ++first1;
|
|
|
- ++first3;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_cached_compose_not_3
|
|
|
-// Description: One of several support functions for
|
|
|
-// tmap_cached_compose(), below, this handles the case
|
|
|
-// of tmap_cached_compose() for an NodeTransition that
|
|
|
-// is already known not to be present in list 3, but may
|
|
|
-// be in one or both of lists 1 and 2.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-void
|
|
|
-tmap_cached_compose_not_3(InputIterator1 &first1, InputIterator2 &first2,
|
|
|
- UpdateSeq now, OutputIterator &result) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- // Here's an element in list 1 that is not in lists 2 or 3.
|
|
|
- OUTPUT_CC_ELEM("1", (*first1).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- ((*first1).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- now));
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
-
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- // Here's an element in list 2 that is not lists 1 or 3.
|
|
|
- OUTPUT_CC_ELEM("2", (*first2).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first2).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- (NodeTransitionCacheEntry(),
|
|
|
- (*first2).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- now));
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
-
|
|
|
- } else { // (*first1).first == (*first2).first
|
|
|
- // Here's an element in lists 1 and 2 that is not in list 3.
|
|
|
- OUTPUT_CC_ELEM("1, 2", (*first1).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- ((*first1).second,
|
|
|
- (*first2).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- now));
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_cached_compose_12
|
|
|
-// Description: One of several support functions for
|
|
|
-// tmap_cached_compose(), below, this handles the case
|
|
|
-// of tmap_cached_compose() for an NodeTransition that
|
|
|
-// is already known to be in both lists 1 and 2, and may
|
|
|
-// or may not also be in list 3.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class InputIterator3,
|
|
|
- class OutputIterator>
|
|
|
-void
|
|
|
-tmap_cached_compose_12(InputIterator1 &first1, InputIterator2 &first2,
|
|
|
- InputIterator3 &first3,
|
|
|
- UpdateSeq now, OutputIterator &result) {
|
|
|
- if ((*first1).first < (*first3).first) {
|
|
|
- // Here's an element in lists 1 and 2 that is not in list 3.
|
|
|
- OUTPUT_CC_ELEM("1, 2", (*first1).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- ((*first1).second,
|
|
|
- (*first2).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- now));
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
-
|
|
|
- } else if ((*first3).first < (*first1).first) {
|
|
|
- // Here's an element in list 3 that is not lists 1 or 2.
|
|
|
- OUTPUT_CC_ELEM("3", (*first3).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first3).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- (NodeTransitionCacheEntry(),
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- (*first3).second,
|
|
|
- now));
|
|
|
- ++first3;
|
|
|
- ++result;
|
|
|
-
|
|
|
- } else { // (*first1).first == (*first3).first
|
|
|
- // Here's an element in lists 1, 2, and 3.
|
|
|
- OUTPUT_CC_ELEM("1, 2, 3", (*first1).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- ((*first1).second,
|
|
|
- (*first2).second,
|
|
|
- (*first3).second,
|
|
|
- now));
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++first3;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_cached_compose
|
|
|
-// Description: Calls dynamic_cached_compose() on each matching
|
|
|
-// element of [first1 .. last1), [cached_first
|
|
|
-// .. cached_last), and [value_first .. value_last).
|
|
|
-//
|
|
|
-// This function is big and complicated because it has
|
|
|
-// to do a parallel merge on three separate lists. Any
|
|
|
-// NodeTransition type may appear in any or all of the
|
|
|
-// lists; if a particular type appears in any list but
|
|
|
-// is absent from the others, an implicit identity
|
|
|
-// transition should be inferred where it is absent.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class InputIterator3,
|
|
|
- class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_cached_compose(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- InputIterator3 first3, InputIterator3 last3,
|
|
|
- UpdateSeq now, OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2 && first3 != last3) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- tmap_cached_compose_not_2(first1, first3, now, result);
|
|
|
-
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- tmap_cached_compose_not_1(first2, first3, now, result);
|
|
|
-
|
|
|
- } else { // (*first1).first == (*first2).first
|
|
|
- tmap_cached_compose_12(first1, first2, first3, now, result);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Now pick up everything else.
|
|
|
- if (first1 == last1) {
|
|
|
- while (first2 != last2 && first3 != last3) {
|
|
|
- tmap_cached_compose_not_1(first2, first3, now, result);
|
|
|
- }
|
|
|
-
|
|
|
- } else if (first2 == last2) {
|
|
|
- while (first1 != last1 && first3 != last3) {
|
|
|
- tmap_cached_compose_not_2(first1, first3, now, result);
|
|
|
- }
|
|
|
-
|
|
|
- } else if (first3 == last3) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- tmap_cached_compose_not_3(first1, first2, now, result);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- // Here's an element in list 1 that is not in lists 2 or 3.
|
|
|
- OUTPUT_CC_ELEM("1", (*first1).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- ((*first1).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- now));
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- // Here's an element in list 2 that is not in lists 1 or 3.
|
|
|
- OUTPUT_CC_ELEM("2", (*first2).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first2).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- (NodeTransitionCacheEntry(),
|
|
|
- (*first2).second,
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- now));
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first3 != last3) {
|
|
|
- // Here's an element in list 3 that is not lists 1 or 2.
|
|
|
- OUTPUT_CC_ELEM("3", (*first3).first);
|
|
|
-
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first3).first,
|
|
|
- NodeTransitionCacheEntry::cached_compose
|
|
|
- (NodeTransitionCacheEntry(),
|
|
|
- NodeTransitionCacheEntry(),
|
|
|
- (*first3).second,
|
|
|
- now));
|
|
|
- ++first3;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_apply
|
|
|
-// Description: Accepts a NodeAttribute map and a NodeTransition map,
|
|
|
-// and builds a new list (a NodeAttribute map) which
|
|
|
-// represents the memberwise application of the two
|
|
|
-// input maps.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_apply(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2,
|
|
|
- OutputIterator result) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- *result = pair<TypeHandle, PT(NodeAttribute) >
|
|
|
- ((*first2).first,
|
|
|
- NodeTransitionCacheEntry::apply(NULL, (*first2).second));
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- } else {
|
|
|
- *result = pair<TypeHandle, PT(NodeAttribute) >
|
|
|
- ((*first1).first,
|
|
|
- NodeTransitionCacheEntry::apply((*first1).second, (*first2).second));
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- *result = *first1;
|
|
|
- ++first1;
|
|
|
- ++result;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- *result = pair<TypeHandle, PT(NodeAttribute) >
|
|
|
- ((*first2).first,
|
|
|
- NodeTransitionCacheEntry::apply(NULL, (*first2).second));
|
|
|
- ++first2;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_invert
|
|
|
-// Description: Accepts a NodeTransition map, and builds a new list
|
|
|
-// which represents the memberwise inversion of the
|
|
|
-// input. Guarantees that the new list will have
|
|
|
-// exactly the same length as the input list.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator, class OutputIterator>
|
|
|
-OutputIterator
|
|
|
-tmap_invert(InputIterator first, InputIterator last,
|
|
|
- OutputIterator result) {
|
|
|
- while (first != last) {
|
|
|
- *result = pair<TypeHandle, NodeTransitionCacheEntry>
|
|
|
- ((*first).first, NodeTransitionCacheEntry::invert((*first).second));
|
|
|
- ++first;
|
|
|
- ++result;
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_equiv_trans
|
|
|
-// Description: Accepts a pair of NodeTransition maps, and returns
|
|
|
-// true if they are equivalent, false otherwise. Two
|
|
|
-// NodeTransition maps are defined to be equivalent if
|
|
|
-// all nonidentity members present in one set are
|
|
|
-// present and equivalent in the other set,
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2>
|
|
|
-bool
|
|
|
-tmap_equiv_trans(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- if (!(*first1).second.is_identity()) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- if (!(*first2).second.is_identity()) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- } else {
|
|
|
- if (!(*first1).second.compare_to((*first2).second) == 0) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- if (!(*first1).second.is_identity()) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- if (!(*first2).second.is_identity()) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_equiv_attr
|
|
|
-// Description: Accepts a pair of NodeAttribute maps, and returns
|
|
|
-// true if they are equivalent, false otherwise. Two
|
|
|
-// NodeAttributes maps are defined to be equivalent if
|
|
|
-// all non-NULL members present in one set are present
|
|
|
-// and equivalent in the other set,
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2>
|
|
|
-bool
|
|
|
-tmap_equiv_attr(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- if ((*first1).second != (NodeAttribute *)NULL) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- if ((*first2).second != (NodeAttribute *)NULL) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- } else {
|
|
|
- if ((*first1).second != (*first2).second) {
|
|
|
- if ((*first1).second == (NodeAttribute *)NULL ||
|
|
|
- (*first2).second == (NodeAttribute *)NULL ||
|
|
|
- (*first1).second->compare_to((*first2).second) != 0) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- if ((*first1).second != (NodeAttribute *)NULL) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- if ((*first2).second != (NodeAttribute *)NULL) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_compare_cache
|
|
|
-// Description: Accepts a pair of NodeTransition maps, and returns
|
|
|
-// -1 if the first one sorts before the second one,
|
|
|
-// 1 if it sorts after, or 0 if they are equivalent.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2>
|
|
|
-int
|
|
|
-tmap_compare_cache(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- if (!(*first1).second.is_identity()) {
|
|
|
- return 1;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- if (!(*first2).second.is_identity()) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- } else {
|
|
|
- int result;
|
|
|
- result = (*first1).second.compare_to((*first2).second);
|
|
|
- if (result != 0) {
|
|
|
- return result;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- if (!(*first1).second.is_identity()) {
|
|
|
- // list1 is longer.
|
|
|
- return -1;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- if (!(*first2).second.is_identity()) {
|
|
|
- // list2 is longer.
|
|
|
- return 1;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_compare_trans
|
|
|
-// Description: Accepts a pair of NodeTransition maps, and returns
|
|
|
-// -1 if the first one sorts before the second one,
|
|
|
-// 1 if it sorts after, or 0 if they are equivalent.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2>
|
|
|
-int
|
|
|
-tmap_compare_trans(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- if ((*first1).second != (NodeTransition *)NULL) {
|
|
|
- return 1;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- if ((*first2).second != (NodeTransition *)NULL) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- } else {
|
|
|
- if ((*first1).second != (*first2).second) {
|
|
|
- if ((*first1).second == (NodeTransition *)NULL) {
|
|
|
- return -1;
|
|
|
- } else if ((*first2).second == (NodeTransition *)NULL) {
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- int result;
|
|
|
- result = (*first1).second->compare_to(*(*first2).second);
|
|
|
- if (result != 0) {
|
|
|
- return result;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- if ((*first1).second != (NodeTransition *)NULL) {
|
|
|
- // list1 is longer.
|
|
|
- return -1;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- if ((*first2).second != (NodeTransition *)NULL) {
|
|
|
- // list2 is longer.
|
|
|
- return 1;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_compare_attr
|
|
|
-// Description: Accepts a pair of NodeAttribute maps, and returns
|
|
|
-// -1 if the first one sorts before the second one,
|
|
|
-// 1 if it sorts after, or 0 if they are equivalent.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator1, class InputIterator2>
|
|
|
-int
|
|
|
-tmap_compare_attr(InputIterator1 first1, InputIterator1 last1,
|
|
|
- InputIterator2 first2, InputIterator2 last2) {
|
|
|
- while (first1 != last1 && first2 != last2) {
|
|
|
- if ((*first1).first < (*first2).first) {
|
|
|
- if ((*first1).second != (NodeAttribute *)NULL) {
|
|
|
- return 1;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- } else if ((*first2).first < (*first1).first) {
|
|
|
- if ((*first2).second != (NodeAttribute *)NULL) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- } else {
|
|
|
- if ((*first1).second != (*first2).second) {
|
|
|
- if ((*first1).second == (NodeAttribute *)NULL) {
|
|
|
- return -1;
|
|
|
- } else if ((*first2).second == (NodeAttribute *)NULL) {
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- int result;
|
|
|
- result = (*first1).second->compare_to(*(*first2).second);
|
|
|
- if (result != 0) {
|
|
|
- return result;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- ++first2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- while (first1 != last1) {
|
|
|
- if ((*first1).second != (NodeAttribute *)NULL) {
|
|
|
- // list1 is longer.
|
|
|
- return -1;
|
|
|
- }
|
|
|
- ++first1;
|
|
|
- }
|
|
|
-
|
|
|
- while (first2 != last2) {
|
|
|
- if ((*first2).second != (NodeAttribute *)NULL) {
|
|
|
- // list2 is longer.
|
|
|
- return 1;
|
|
|
- }
|
|
|
- ++first2;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_is_identity
|
|
|
-// Description: Accepts a NodeTransition map, and returns true if all
|
|
|
-// elements in the map correspond to the identity
|
|
|
-// transition, false otherwise.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator>
|
|
|
-bool
|
|
|
-tmap_is_identity(InputIterator first, InputIterator last) {
|
|
|
- while (first != last) {
|
|
|
- if (!(*first).second.is_identity()) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first;
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_is_initial
|
|
|
-// Description: Accepts a NodeAttribute map, and returns true if all
|
|
|
-// elements in the map correspond to the initial
|
|
|
-// attribute, false otherwise.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator>
|
|
|
-bool
|
|
|
-tmap_is_initial(InputIterator first, InputIterator last) {
|
|
|
- while (first != last) {
|
|
|
- if (!(*first).second.is_initial()) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- ++first;
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: tmap_output
|
|
|
-// Description: Accepts a NodeTransition or NodeAttribute map and
|
|
|
-// writes each element to the given output stream with a
|
|
|
-// single space separating them.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-template<class InputIterator>
|
|
|
-ostream &
|
|
|
-tmap_output(InputIterator first, InputIterator last, ostream &out) {
|
|
|
- if (first != last) {
|
|
|
- out << *((*first).second);
|
|
|
- ++first;
|
|
|
- while (first != last) {
|
|
|
- out << " " << *((*first).second);
|
|
|
- ++first;
|
|
|
- }
|
|
|
- }
|
|
|
- return out;
|
|
|
-}
|