#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
template <class KeyType, class ValueVectorType>
struct MyKeyWrapper { // all is public to save getters
KeyType k;
bool operator <(const MyKeyWrapper &other) const { return k < other.k; }
};
template <class KeyType, class ValueVectorType>
struct ValueVectorSingleton { // all is public to save getters, but kv and vv should be only accessible by getters
static std::vector<MyKeyWrapper<KeyType, ValueVectorType> > *kv;
static ValueVectorType *vv;
static void StartSort(std::vector<MyKeyWrapper<KeyType, ValueVectorType> > &_kv, ValueVectorType &_vv)
{
assert(!kv && !vv); // can't sort two at once (if multithreading)
assert(_kv.size() == _vv.size());
kv = &_kv, vv = &_vv; // not an attempt for atomic operation
}
static void EndSort()
{
kv = 0, vv = 0;
}
};
template <class KeyType, class ValueVectorType>
std::vector<MyKeyWrapper<KeyType, ValueVectorType> >
*ValueVectorSingleton<KeyType, ValueVectorType>::kv = 0;
template <class KeyType, class ValueVectorType>
ValueVectorType *ValueVectorSingleton<KeyType, ValueVectorType>::vv = 0;
namespace std {
template <class KeyType, class ValueVectorType>
void swap(MyKeyWrapper<KeyType, ValueVectorType> &a, MyKeyWrapper<KeyType, ValueVectorType> &b)
{
assert((ValueVectorSingleton<KeyType, ValueVectorType>::vv &&
ValueVectorSingleton<KeyType, ValueVectorType>::kv)); // if this triggers, someone forgot to call StartSort()
ValueVectorType &vv = *ValueVectorSingleton<KeyType, ValueVectorType>::vv;
std::vector<MyKeyWrapper<KeyType, ValueVectorType> > &kv =
*ValueVectorSingleton<KeyType, ValueVectorType>::kv;
size_t ai = &kv.front() - &a, bi = &kv.front() - &b; // get indices in key vector
std::swap(a, b); // swap keys
std::swap(vv[ai], vv[bi]); // and any associated values
}
} // ~std
int main()
{
size_t keys[] = {5, 2, 3, 1, 4};
char values[] = {'e', 'b', 'd', 'c', 'a'};
std::vector<char> vv(values, values + 5); // fill by values
typedef MyKeyWrapper<size_t, std::vector<char> > KV;
assert(sizeof(KV) == sizeof(size_t)); // otherwise this will crash
std::vector<KV> kv((KV*)keys, (KV*)keys + 5); // fill by keys, casted to MyKeyWrapper
ValueVectorSingleton<size_t, std::vector<char> >::StartSort(kv, vv);
std::sort(kv.begin(), kv.end());
ValueVectorSingleton<size_t, std::vector<char> >::EndSort();
// trick std::sort into using the custom std::swap which also swaps the other vectors
for(int i = 0; i < 5; ++ i)
std::cout << kv[i].k << " ";
std::cout << std::endl;
for(int i = 0; i < 5; ++ i)
std::cout << vv[i] << " ";
std::cout << std::endl;
// could have used for_each and lambdas
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8Y2Fzc2VydD4KCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgS2V5VHlwZSwgY2xhc3MgVmFsdWVWZWN0b3JUeXBlPgogICAgc3RydWN0IE15S2V5V3JhcHBlciB7IC8vIGFsbCBpcyBwdWJsaWMgdG8gc2F2ZSBnZXR0ZXJzCiAgICAgICAgS2V5VHlwZSBrOwogICAgICAgIGJvb2wgb3BlcmF0b3IgPChjb25zdCBNeUtleVdyYXBwZXIgJm90aGVyKSBjb25zdCB7IHJldHVybiBrIDwgb3RoZXIuazsgfQogICAgfTsKCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgS2V5VHlwZSwgY2xhc3MgVmFsdWVWZWN0b3JUeXBlPgogICAgc3RydWN0IFZhbHVlVmVjdG9yU2luZ2xldG9uIHsgLy8gYWxsIGlzIHB1YmxpYyB0byBzYXZlIGdldHRlcnMsIGJ1dCBrdiBhbmQgdnYgc2hvdWxkIGJlIG9ubHkgYWNjZXNzaWJsZSBieSBnZXR0ZXJzCiAgICAgICAgc3RhdGljIHN0ZDo6dmVjdG9yPE15S2V5V3JhcHBlcjxLZXlUeXBlLCBWYWx1ZVZlY3RvclR5cGU+ID4gKmt2OwogICAgICAgIHN0YXRpYyBWYWx1ZVZlY3RvclR5cGUgKnZ2OwoKICAgICAgICBzdGF0aWMgdm9pZCBTdGFydFNvcnQoc3RkOjp2ZWN0b3I8TXlLZXlXcmFwcGVyPEtleVR5cGUsIFZhbHVlVmVjdG9yVHlwZT4gPiAmX2t2LCBWYWx1ZVZlY3RvclR5cGUgJl92dikKICAgICAgICB7CiAgICAgICAgICAgIGFzc2VydCgha3YgJiYgIXZ2KTsgLy8gY2FuJ3Qgc29ydCB0d28gYXQgb25jZSAoaWYgbXVsdGl0aHJlYWRpbmcpCiAgICAgICAgICAgIGFzc2VydChfa3Yuc2l6ZSgpID09IF92di5zaXplKCkpOwogICAgICAgICAgICBrdiA9ICZfa3YsIHZ2ID0gJl92djsgLy8gbm90IGFuIGF0dGVtcHQgZm9yIGF0b21pYyBvcGVyYXRpb24KICAgICAgICB9CgogICAgICAgIHN0YXRpYyB2b2lkIEVuZFNvcnQoKQogICAgICAgIHsKICAgICAgICAgICAga3YgPSAwLCB2diA9IDA7CiAgICAgICAgfQogICAgfTsKCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgS2V5VHlwZSwgY2xhc3MgVmFsdWVWZWN0b3JUeXBlPgogICAgc3RkOjp2ZWN0b3I8TXlLZXlXcmFwcGVyPEtleVR5cGUsIFZhbHVlVmVjdG9yVHlwZT4gPgogICAgICAgICpWYWx1ZVZlY3RvclNpbmdsZXRvbjxLZXlUeXBlLCBWYWx1ZVZlY3RvclR5cGU+OjprdiA9IDA7CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgS2V5VHlwZSwgY2xhc3MgVmFsdWVWZWN0b3JUeXBlPgogICAgVmFsdWVWZWN0b3JUeXBlICpWYWx1ZVZlY3RvclNpbmdsZXRvbjxLZXlUeXBlLCBWYWx1ZVZlY3RvclR5cGU+Ojp2diA9IDA7CgogICAgbmFtZXNwYWNlIHN0ZCB7CgogICAgdGVtcGxhdGUgPGNsYXNzIEtleVR5cGUsIGNsYXNzIFZhbHVlVmVjdG9yVHlwZT4KICAgIHZvaWQgc3dhcChNeUtleVdyYXBwZXI8S2V5VHlwZSwgVmFsdWVWZWN0b3JUeXBlPiAmYSwgTXlLZXlXcmFwcGVyPEtleVR5cGUsIFZhbHVlVmVjdG9yVHlwZT4gJmIpCiAgICB7CiAgICAgICAgYXNzZXJ0KChWYWx1ZVZlY3RvclNpbmdsZXRvbjxLZXlUeXBlLCBWYWx1ZVZlY3RvclR5cGU+Ojp2diAmJgogICAgICAgICAgICBWYWx1ZVZlY3RvclNpbmdsZXRvbjxLZXlUeXBlLCBWYWx1ZVZlY3RvclR5cGU+OjprdikpOyAvLyBpZiB0aGlzIHRyaWdnZXJzLCBzb21lb25lIGZvcmdvdCB0byBjYWxsIFN0YXJ0U29ydCgpCiAgICAgICAgVmFsdWVWZWN0b3JUeXBlICZ2diA9ICpWYWx1ZVZlY3RvclNpbmdsZXRvbjxLZXlUeXBlLCBWYWx1ZVZlY3RvclR5cGU+Ojp2djsKICAgICAgICBzdGQ6OnZlY3RvcjxNeUtleVdyYXBwZXI8S2V5VHlwZSwgVmFsdWVWZWN0b3JUeXBlPiA+ICZrdiA9CiAgICAgICAgICAgICpWYWx1ZVZlY3RvclNpbmdsZXRvbjxLZXlUeXBlLCBWYWx1ZVZlY3RvclR5cGU+OjprdjsKICAgICAgICBzaXplX3QgYWkgPSAma3YuZnJvbnQoKSAtICZhLCBiaSA9ICZrdi5mcm9udCgpIC0gJmI7IC8vIGdldCBpbmRpY2VzIGluIGtleSB2ZWN0b3IKICAgICAgICBzdGQ6OnN3YXAoYSwgYik7IC8vIHN3YXAga2V5cwogICAgICAgIHN0ZDo6c3dhcCh2dlthaV0sIHZ2W2JpXSk7IC8vIGFuZCBhbnkgYXNzb2NpYXRlZCB2YWx1ZXMKICAgIH0KCiAgICB9IC8vIH5zdGQKCmludCBtYWluKCkKewogICAgc2l6ZV90IGtleXNbXSA9IHs1LCAyLCAzLCAxLCA0fTsKICAgIGNoYXIgdmFsdWVzW10gPSB7J2UnLCAnYicsICdkJywgJ2MnLCAnYSd9OwoKICAgIHN0ZDo6dmVjdG9yPGNoYXI+IHZ2KHZhbHVlcywgdmFsdWVzICsgNSk7IC8vIGZpbGwgYnkgdmFsdWVzCiAgICB0eXBlZGVmIE15S2V5V3JhcHBlcjxzaXplX3QsIHN0ZDo6dmVjdG9yPGNoYXI+ID4gS1Y7CiAgICBhc3NlcnQoc2l6ZW9mKEtWKSA9PSBzaXplb2Yoc2l6ZV90KSk7IC8vIG90aGVyd2lzZSB0aGlzIHdpbGwgY3Jhc2gKICAgIHN0ZDo6dmVjdG9yPEtWPiBrdigoS1YqKWtleXMsIChLViopa2V5cyArIDUpOyAvLyBmaWxsIGJ5IGtleXMsIGNhc3RlZCB0byBNeUtleVdyYXBwZXIKCiAgICBWYWx1ZVZlY3RvclNpbmdsZXRvbjxzaXplX3QsIHN0ZDo6dmVjdG9yPGNoYXI+ID46OlN0YXJ0U29ydChrdiwgdnYpOwogICAgc3RkOjpzb3J0KGt2LmJlZ2luKCksIGt2LmVuZCgpKTsKICAgIFZhbHVlVmVjdG9yU2luZ2xldG9uPHNpemVfdCwgc3RkOjp2ZWN0b3I8Y2hhcj4gPjo6RW5kU29ydCgpOwogICAgLy8gdHJpY2sgc3RkOjpzb3J0IGludG8gdXNpbmcgdGhlIGN1c3RvbSBzdGQ6OnN3YXAgd2hpY2ggYWxzbyBzd2FwcyB0aGUgb3RoZXIgdmVjdG9ycwoKICAgIGZvcihpbnQgaSA9IDA7IGkgPCA1OyArKyBpKQogICAgICAgIHN0ZDo6Y291dCA8PCBrdltpXS5rIDw8ICIgIjsKICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7CiAgICBmb3IoaW50IGkgPSAwOyBpIDwgNTsgKysgaSkKICAgICAgICBzdGQ6OmNvdXQgPDwgdnZbaV0gPDwgIiAiOwogICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKICAgIC8vIGNvdWxkIGhhdmUgdXNlZCBmb3JfZWFjaCBhbmQgbGFtYmRhcwogICAgCglyZXR1cm4gMDsKfQ==