#include #include #include using namespace std; namespace My_region { template void show(char* titolo,const C& c) { cout << titolo << " (size=" << c.size() << "): "; typename C::const_iterator cit = c.begin(); while(cit != c.end()) cout << *cit++ << " "; cout << '\n'; } struct Error { int first, last, out; Error(int f, int l, int o) : first(f), last(l), out (o) {} }; template void move(C& c, int first, int last, int out) { if ( first < 0 || last <= first || last > c.size() || out < 0 || out > c.size() ) throw(Error(first,last,out)); if ( first == out ) return; int range = last-first; int out_last = out+range; bool backward = false; typename C::iterator first_erase; typename C::iterator last_erase; typename C::iterator first_copy; typename C::iterator last_copy; typename C::iterator out_copy; if ( out_last > c.size() ) // inserire nuovi elementi { int d = out_last-c.size(); first_copy = c.begin(); advance(first_copy,last-d); last_copy = first_copy; advance(last_copy,d); copy(first_copy,last_copy,back_inserter(c)); c.erase(first_copy,last_copy); last -= d; out -= d; if ( last == first || out == first ) return; range -= d; out_last = out+range; } first_copy = c.begin(); if ( first > 0 ) advance(first_copy,first); last_copy = first_copy; advance(last_copy,range); first_erase = first_copy; last_erase = last_copy; out_copy = c.begin(); if ( out > 0 ) advance(out_copy,out); if ( first > out && first < out_last ) //sequenze sovrapposte con seq. di uscita prima { first_erase = c.begin(); advance(first_erase,out_last); } else if ( out > first && out < last ) //sequenze sovrapposte con seq. di uscita dopo { last_erase = c.begin(); advance(last_erase,out); backward = true; advance(out_copy,range); } if ( backward ) copy_backward(first_copy,last_copy,out_copy); else copy(first_copy,last_copy,out_copy); c.erase(first_erase,last_erase); } } int main() { using My_region::show; using My_region::move; using My_region::Error; list list_origin, list_mv; int i = 0; while ( i < 10 ) list_origin.push_back(i++); try { show("\nOggetto originale",list_origin); list_mv = list_origin; move(list_mv,1,3,6); show("Mossa sequenza 1-3 in 6 - sequenze non sovrapposte\n con seq. di\ uscita dopo",list_mv); show("\nOggetto originale",list_origin); list_mv = list_origin; move(list_mv,7,10,2); show("Mossa sequenza 7-10 in 2 - sequenze non sovrapposte\n con seq. di\ uscita prima",list_mv); show("\nOggetto originale",list_origin); list_mv = list_origin; move(list_mv,1,4,3); show("Mossa sequenza 1-4 in 3 - sequenze sovrapposte\n con seq. di\ uscita dopo",list_mv); show("\nOggetto originale",list_origin); list_mv = list_origin; move(list_mv,6,9,5); show("Mossa sequenza 6-9 in 5 - sequenze sovrapposte\n con seq. di\ uscita prima",list_mv); show("\nOggetto originale",list_origin); list_mv = list_origin; move(list_mv,3,6,9); show("Mossa sequenza 3-6 in 9 - sequenze non sovrapposte\n con\ inserimento in coda",list_mv); show("\nOggetto originale",list_origin); list_mv = list_origin; move(list_mv,2,7,6); show("Mossa sequenza 2-7 in 6 - sequenze sovrapposte\n con\ inserimento in coda",list_mv); show("\nOggetto originale",list_origin); list_mv = list_origin; move(list_mv,0,4,10); show("Mossa sequenza 0-4 in 10 - spostamento\n\ primi 4 elementi in coda",list_mv); show("\nOggetto originale",list_origin); list_mv = list_origin; cout << "Mossa sequenza con .... "; move(list_mv,4,4,11); } catch (Error e) { cout << "dati non validi: " << e.first << " " << e.last << " " << e.out << '\n'; } return 0; }