#pragma once #include "std/bind.hpp" #include "std/algorithm.hpp" #include "std/vector.hpp" #include "std/limits.hpp" namespace search { /// Intrusive class to implement multi-index for some user-defined type. template class IndexedValueBase { protected: static size_t const SIZE = N; size_t m_ind[N]; public: IndexedValueBase() { for (size_t i = 0; i < N; ++i) m_ind[i] = numeric_limits::max(); } void SetIndex(size_t i, size_t v) { m_ind[i] = v; } void SortIndex() { sort(m_ind, m_ind + N); } static bool Less(IndexedValueBase const & r1, IndexedValueBase const & r2) { for (size_t i = 0; i < N; ++i) { if (r1.m_ind[i] != r2.m_ind[i]) return (r1.m_ind[i] < r2.m_ind[i]); } return false; } }; template void SortByIndexedValue(vector & vec, CompFactory factory) { for (size_t i = 0; i < CompFactory::SIZE; ++i) { typename CompFactory::CompT comp = factory.Get(i); // sort by needed criteria sort(vec.begin(), vec.end(), comp); // assign ranks size_t rank = 0; for (size_t j = 0; j < vec.size(); ++j) { if (j > 0 && comp(vec[j-1], vec[j])) ++rank; vec[j].SetIndex(i, rank); } } // prepare combined criteria for_each(vec.begin(), vec.end(), [] (IndexedValueBase & p) { p.SortIndex(); }); // sort results according to combined criteria sort(vec.begin(), vec.end(), &IndexedValueBase::Less); } }