| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- // Filename: multiTransitionHelpers.I
- // Created by: drose (15Feb99)
- //
- ////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////
- // Function: dmap_compose
- // Description: Accepts two DirectionMaps, and builds a new
- // list (another DirectionMap) which represents the
- // memberwise composition of the two input maps.
- ////////////////////////////////////////////////////////////////////
- template<class InputIterator1, class InputIterator2, class OutputIterator>
- OutputIterator
- dmap_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 {
- // If the second Transition is identity, it has no effect.
- // Otherwise, it replaces us.
- if ((*first2).second != TD_identity) {
- *result = *first2;
- } else {
- *result = *first1;
- }
- ++first1;
- ++first2;
- ++result;
- }
- }
- while (first1 != last1) {
- *result = *first1;
- ++first1;
- ++result;
- }
- while (first2 != last2) {
- *result = *first2;
- ++first2;
- ++result;
- }
- return result;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: dmap_invert_compose
- // Description: Accepts two DirectionMaps, and builds a new
- // list (another DirectionMap) which represents the
- // memberwise result inverting and composing.
- ////////////////////////////////////////////////////////////////////
- template<class InputIterator1, class InputIterator2, class OutputIterator>
- OutputIterator
- dmap_invert_compose(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2,
- OutputIterator result) {
- typedef TYPENAME InputIterator1::value_type OutputType;
- while (first1 != last1 && first2 != last2) {
- if ((*first1).first < (*first2).first) {
- (*result) = OutputType((*first1).first, TD_inverse);
- ++first1;
- ++result;
- } else if ((*first2).first < (*first1).first) {
- *result = *first2;
- ++first2;
- ++result;
- } else {
- TransitionDirection dir1 = (*first1).second;
- TransitionDirection dir2 = (*first2).second;
- if (dir1 == dir2 &&
- (dir1 != TD_normal || (*first1).first == (*first2).first)) {
- // The two transitions are equivalent, so the invert_compose
- // will be identity. Don't bother to store it.
- } else {
- if ((*first2).second != TD_identity) {
- *result = *first2;
- } else {
- (*result) = OutputType((*first1).first, TD_inverse);
- }
- ++result;
- }
- ++first1;
- ++first2;
- }
- }
- while (first1 != last1) {
- (*result) = OutputType((*first1).first, TD_inverse);
- ++first1;
- ++result;
- }
- while (first2 != last2) {
- *result = *first2;
- ++first2;
- ++result;
- }
- return result;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: dmap_invert
- // Description: Accepts a DirectionMap, 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
- dmap_invert(InputIterator first, InputIterator last,
- OutputIterator result) {
- typedef TYPENAME InputIterator::value_type OutputType;
- while (first != last) {
- switch ((*first).second) {
- case TD_identity:
- (*result) = OutputType((*first).first, TD_identity);
- ++result;
- break;
- case TD_on:
- (*result) = OutputType((*first).first, TD_off);
- ++result;
- break;
- case TD_off:
- (*result) = OutputType((*first).first, TD_on);
- ++result;
- break;
- }
- ++first;
- }
- return result;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: dmap_equiv
- // Description: Accepts a pair of DirectionMaps, and returns
- // true if they are equivalent, false otherwise. Two
- // DirectionMaps 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
- dmap_equiv(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2) {
- while (first1 != last1 && first2 != last2) {
- if ((*first1).first < (*first2).first) {
- if ((*first1).second != TD_identity) {
- return false;
- }
- ++first1;
- } else if ((*first2).first < (*first1).first) {
- if ((*first2).second != TD_identity) {
- return false;
- }
- ++first2;
- } else {
- TransitionDirection dir1 = (*first1).second;
- TransitionDirection dir2 = (*first2).second;
- if (dir1 != dir2) {
- return false;
- }
- ++first1;
- ++first2;
- }
- }
- while (first1 != last1) {
- if ((*first1).second != TD_identity) {
- return false;
- }
- ++first1;
- }
- while (first2 != last2) {
- if ((*first2).second != TD_identity) {
- return false;
- }
- ++first2;
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: dmap_compare
- // Description: Accepts a pair of DirectionMaps, and returns
- // < 0 if the first one sorts before the second one, > 0
- // if the first one sorts after, 0 if they are
- // equivalent.
- ////////////////////////////////////////////////////////////////////
- template<class InputIterator1, class InputIterator2>
- int
- dmap_compare(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2) {
- while (first1 != last1 && first2 != last2) {
- if ((*first1).first < (*first2).first) {
- if ((*first1).second != TD_identity) {
- // list1 has the first value that does not appear in list2.
- return 1;
- }
- ++first1;
- } else if ((*first2).first < (*first1).first) {
- if ((*first2).second != TD_identity) {
- // list2 has the first value that does not appear in list1.
- return -1;
- }
- ++first2;
- } else {
- TransitionDirection dir1 = (*first1).second;
- TransitionDirection dir2 = (*first2).second;
- if (dir1 != dir2) {
- if (dir1 == TD_identity) {
- // list1 has the first value that does not appear in list2.
- return 1;
- } else if (dir2 == TD_identity) {
- // list2 has the first value that does not appear in list1.
- return -1;
- }
-
- // This value appears in both lists, but it is TD_normal in
- // one and TD_inverse in the other.
- return (dir1 < dir2) ? -1 : 1;
- }
- ++first1;
- ++first2;
- }
- }
- while (first1 != last1) {
- if ((*first1).second != TD_identity) {
- // list1 is longer.
- return -1;
- }
- ++first1;
- }
- while (first2 != last2) {
- if ((*first2).second != TD_identity) {
- // list2 is longer.
- return 1;
- }
- ++first2;
- }
- return 0;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: dmap_is_identity
- // Description: Accepts a DirectionMap, and returns true if all
- // elements in the map correspond to the identity
- // transition, false otherwise.
- ////////////////////////////////////////////////////////////////////
- template<class InputIterator>
- bool
- dmap_is_identity(InputIterator first, InputIterator last) {
- while (first != last) {
- if ((*first).second != TD_identity) {
- return false;
- }
- ++first;
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: bmap_equiv
- // Description: Accepts a pair of BoolMaps, and returns true if they
- // are equivalent, false otherwise. Two BoolMaps are
- // defined to be equivalent if all 'on' members present
- // in one set are present and equivalent in the other
- // set,
- ////////////////////////////////////////////////////////////////////
- template<class InputIterator1, class InputIterator2>
- bool
- bmap_equiv(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2) {
- while (first1 != last1 && first2 != last2) {
- if ((*first1) < (*first2)) {
- return false;
- } else if ((*first2) < (*first1)) {
- return false;
- } else {
- ++first1;
- ++first2;
- }
- }
- if (first1 != last1 || first2 != last2) {
- return false;
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: bmap_compare
- // Description: Accepts a pair of BoolMaps, and returns < 0 if the
- // first one sorts first, > 0 if the second one sorts
- // first, 0 if they are equivalent.
- ////////////////////////////////////////////////////////////////////
- template<class InputIterator1, class InputIterator2>
- int
- bmap_compare(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2) {
- while (first1 != last1 && first2 != last2) {
- if ((*first1) < (*first2)) {
- return -1;
- } else if ((*first2) < (*first1)) {
- return 1;
- } else {
- ++first1;
- ++first2;
- }
- }
- if (first1 != last1) {
- // list 1 is longer.
- return -1;
- }
- if (first2 != last2) {
- // list 2 is longer.
- return 1;
- }
- return 0;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: bmap_apply
- // Description: Accepts a BoolMap and a DirectionMap, and builds a
- // new list (another BoolMap) which represents the
- // memberwise application of the two input maps.
- ////////////////////////////////////////////////////////////////////
- template<class InputIterator1, class InputIterator2, class OutputIterator>
- OutputIterator
- bmap_apply(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2,
- bool complete_transition, TransitionDirection want_dirs,
- OutputIterator result) {
- while (first1 != last1 && first2 != last2) {
- if ((*first1) < (*first2).first) {
- // Here's an attribute property that wasn't mentioned by the
- // transition. It stays, unless the transition is "complete".
- if (!complete_transition) {
- *result = *first1;
- ++result;
- }
- ++first1;
- } else if ((*first2).first < (*first1)) {
- // The transition mentions this property that wasn't previously
- // in the attribute. It becomes a member of the attribute only
- // if the transition explicitly turned it on.
- if ((*first2).second == want_dirs) {
- *result = (*first2).first;
- ++result;
- break;
- }
-
- ++first2;
- } else { // ((*first2).first == (*first1))
- // The transition mentions this property that was already in the
- // attribute. Does the transition replace, preserve, or delete
- // the attribute?
- if ((*first2).second == TD_identity) {
- // Preserve.
- *result = *first1;
- ++result;
- } else if ((*first2).second == want_dirs) {
- // Replace.
- *result = (*first2).first;
- ++result;
- } else {
- // Omit.
- }
- ++first1;
- ++first2;
- }
- }
- while (first1 != last1) {
- // Here's an attribute property that wasn't mentioned by the
- // transition. It stays, unless the transition is "complete".
- if (!complete_transition) {
- *result = *first1;
- ++result;
- }
- ++first1;
- }
- while (first2 != last2) {
- // The transition mentions this property that wasn't previously
- // in the attribute. It becomes a member of the attribute only
- // if the transition explicitly turned it on.
-
- if ((*first2).second == want_dirs) {
- *result = (*first2).first;
- ++result;
- break;
- }
-
- ++first2;
- }
- return result;
- }
|