Nel valutatore di un linguaggio personalizzato, vorrei sostituire le nostre routine di ordinamento con std::sort
o altre routine, possibilmente tbb::parallel_sort
. Il problema è che consentiamo agli utenti della lingua di fornire la propria routine di confronto e, nelle implementazioni che ho provato, std::sort
non accetta le routine che non sono rigorose. In particolare, inizia rapidamente a cercare "elementi" al di fuori dell'intervallo iteratore per ordinare.
Suppongo che se inserissi uno strato di riferimento indiretto sugli iteratori, potrei evitarlo usando sentinelle virtuali, ma non c'è ragione di supporre che le chiamate risultanti terminerebbero necessariamente.
Quindi, data una scatola nera bool f(widget const &a, widget const &b)
e un ordine totale non controllato dall'utente operator<(widget const &a, widget const &b)
, quale sarebbe la quantità minima di chiamate che avrei bisogno di fare per ottenere una chiamata di ordinamento che termina e che ordina secondo f
se questo è, in effetti, un ordine? Mi sembra che il seguente dovrebbe funzionare, ma spero che potrei ottenere con meno chiamate a f
con un metodo intelligente, forse ricordando le precedenti chiamate di confronto:
bool f_stabilized(widget const &a, widget const &b) {
bool fab = f(a, b);
bool fba = f(b, a);
return (fab != fba) ? fab : (a < b);
}
Sarebbe ragionevole iniziare chiamando solo f
e solo dopo aver visto n ^ 2 chiamate per un elenco di lunghezza n a ricorrere a una versione così "stabilizzata"? Mi rendo conto che non vi è alcun motivo per ritenere che il risultato sarebbe stato correttamente ordinato e che avrei dovuto ricominciare da capo con tale wrapper.