#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <functional>
using namespace std;
// the name is misleading and shows only what I
// intended when starting to write this code. Now
// a name like weird_thing would probably be more
// appropriate.
template <class T>
class copyable_ref {
public:
copyable_ref(T& ref) noexcept
: _ptr(std::addressof(ref)), _copied(false) {}
copyable_ref(T&&) = delete;
copyable_ref(const copyable_ref& x) noexcept
: _ptr (new int(*x._ptr)), _copied (true) {
cout << "copied " << x._ptr << ":" << *x._ptr << " to " << _ptr << endl;
}
~copyable_ref() {
if (_copied) {
cout << "freed " << _ptr << ":" << *_ptr << endl;
delete _ptr;
}
}
copyable_ref& operator=(const copyable_ref& x) noexcept {
cout << _ptr << ":" << *_ptr << " overwritten with " << x._ptr << ":" << *x._ptr << endl;
*_ptr = *x._ptr;
// _ptr = x._ptr;
}
operator T& () const noexcept { return *_ptr; }
T& get() const noexcept { return *_ptr; }
// unused by sort ... :/
void swap(copyable_ref & x) {
cout << "swap member" << endl;
}
private:
T* _ptr;
bool _copied;
};
// I couldn't convince std::sort to use this.
// That's why the copy constructor of the class
// needs to be so weird.
template<typename T>
void swap(copyable_ref<T> & lhs, copyable_ref<T> & rhs) {
cout << "swap" << endl;
}
int main(int, char **) {
vector<int> input {1,2,3,4,5,6,7,8,9};
// Vector with the references, reserving space isn't
// a performance thing, it's absolutely necessary to
// prevent the vector from copying elements.
vector<copyable_ref<int>> sorted;
sorted.reserve(input.size());
for (auto & e : input) {
if (e % 2 != 0) {
// emplace to prevent calling the copy constructor.
// We need this with references to the real items,
// and not to heap allocated copies of them.
sorted.emplace_back(e);
}
}
copy(begin(sorted), end(sorted),
ostream_iterator<int>{cout, ", "});
cout << endl;
// The actual sorting. This seems to contain code like
// T t(a);
// a = b;
// b = t;
// instead of using swap. This is the reason for the
// strange copy constructor.
sort(begin(sorted), end(sorted),
greater<int>{});
copy(begin(sorted), end(sorted),
ostream_iterator<int>{cout, ", "});
cout << endl;
copy(begin(input), end(input),
ostream_iterator<int>{cout, ", "});
cout << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKLy8gdGhlIG5hbWUgaXMgbWlzbGVhZGluZyBhbmQgc2hvd3Mgb25seSB3aGF0IEkKLy8gaW50ZW5kZWQgd2hlbiBzdGFydGluZyB0byB3cml0ZSB0aGlzIGNvZGUuIE5vdwovLyBhIG5hbWUgbGlrZSB3ZWlyZF90aGluZyB3b3VsZCBwcm9iYWJseSBiZSBtb3JlCi8vIGFwcHJvcHJpYXRlLgp0ZW1wbGF0ZSA8Y2xhc3MgVD4KY2xhc3MgY29weWFibGVfcmVmIHsKcHVibGljOgogIGNvcHlhYmxlX3JlZihUJiByZWYpIG5vZXhjZXB0CiAgOiBfcHRyKHN0ZDo6YWRkcmVzc29mKHJlZikpLCBfY29waWVkKGZhbHNlKSB7fQogIGNvcHlhYmxlX3JlZihUJiYpID0gZGVsZXRlOwogIGNvcHlhYmxlX3JlZihjb25zdCBjb3B5YWJsZV9yZWYmIHgpIG5vZXhjZXB0CiAgOiBfcHRyIChuZXcgaW50KCp4Ll9wdHIpKSwgX2NvcGllZCAodHJ1ZSkgewogICAgY291dCA8PCAiY29waWVkICIgPDwgeC5fcHRyIDw8ICI6IiA8PCAqeC5fcHRyIDw8ICIgdG8gIiA8PCBfcHRyIDw8IGVuZGw7CiAgfQogIH5jb3B5YWJsZV9yZWYoKSB7CiAgICBpZiAoX2NvcGllZCkgewogICAgICBjb3V0IDw8ICJmcmVlZCAiIDw8ICBfcHRyIDw8ICI6IiA8PCAqX3B0ciA8PCBlbmRsOwogICAgICBkZWxldGUgX3B0cjsKICAgIH0KICB9CiAKICBjb3B5YWJsZV9yZWYmIG9wZXJhdG9yPShjb25zdCBjb3B5YWJsZV9yZWYmIHgpIG5vZXhjZXB0IHsKICAgIGNvdXQgPDwgX3B0ciA8PCAiOiIgPDwgKl9wdHIgPDwgIiBvdmVyd3JpdHRlbiB3aXRoICIgPDwgeC5fcHRyIDw8ICI6IiA8PCAqeC5fcHRyIDw8IGVuZGw7CiAgICAqX3B0ciA9ICp4Ll9wdHI7CiAgIC8vIF9wdHIgPSB4Ll9wdHI7CiAgfQogCiAgb3BlcmF0b3IgVCYgKCkgY29uc3Qgbm9leGNlcHQgeyByZXR1cm4gKl9wdHI7IH0KICBUJiBnZXQoKSBjb25zdCBub2V4Y2VwdCB7IHJldHVybiAqX3B0cjsgfQoKICAvLyB1bnVzZWQgYnkgc29ydCAuLi4gOi8KICB2b2lkIHN3YXAoY29weWFibGVfcmVmICYgeCkgewogICAgY291dCA8PCAic3dhcCBtZW1iZXIiIDw8IGVuZGw7CiAgfQogCnByaXZhdGU6CiAgVCogX3B0cjsKICBib29sIF9jb3BpZWQ7Cn07CgovLyBJIGNvdWxkbid0IGNvbnZpbmNlIHN0ZDo6c29ydCB0byB1c2UgdGhpcy4KLy8gVGhhdCdzIHdoeSB0aGUgY29weSBjb25zdHJ1Y3RvciBvZiB0aGUgY2xhc3MKLy8gbmVlZHMgdG8gYmUgc28gd2VpcmQuCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnZvaWQgc3dhcChjb3B5YWJsZV9yZWY8VD4gJiBsaHMsIGNvcHlhYmxlX3JlZjxUPiAmIHJocykgewogIGNvdXQgPDwgInN3YXAiIDw8IGVuZGw7Cn0KCgppbnQgbWFpbihpbnQsIGNoYXIgKiopIHsKIHZlY3RvcjxpbnQ+IGlucHV0IHsxLDIsMyw0LDUsNiw3LDgsOX07CgogLy8gVmVjdG9yIHdpdGggdGhlIHJlZmVyZW5jZXMsIHJlc2VydmluZyBzcGFjZSBpc24ndAogLy8gYSBwZXJmb3JtYW5jZSB0aGluZywgaXQncyBhYnNvbHV0ZWx5IG5lY2Vzc2FyeSB0bwogLy8gcHJldmVudCB0aGUgdmVjdG9yIGZyb20gY29weWluZyBlbGVtZW50cy4KIHZlY3Rvcjxjb3B5YWJsZV9yZWY8aW50Pj4gc29ydGVkOwogc29ydGVkLnJlc2VydmUoaW5wdXQuc2l6ZSgpKTsKIGZvciAoYXV0byAmIGUgOiBpbnB1dCkgewogIGlmIChlICUgMiAhPSAwKSB7CiAgICAvLyBlbXBsYWNlIHRvIHByZXZlbnQgY2FsbGluZyB0aGUgY29weSBjb25zdHJ1Y3Rvci4KICAgIC8vIFdlIG5lZWQgdGhpcyB3aXRoIHJlZmVyZW5jZXMgdG8gdGhlIHJlYWwgaXRlbXMsCiAgICAvLyBhbmQgbm90IHRvIGhlYXAgYWxsb2NhdGVkIGNvcGllcyBvZiB0aGVtLgogICAgc29ydGVkLmVtcGxhY2VfYmFjayhlKTsKICB9CiB9CgogY29weShiZWdpbihzb3J0ZWQpLCBlbmQoc29ydGVkKSwKICAgICAgb3N0cmVhbV9pdGVyYXRvcjxpbnQ+e2NvdXQsICIsICJ9KTsKIGNvdXQgPDwgZW5kbDsKCiAvLyBUaGUgYWN0dWFsIHNvcnRpbmcuIFRoaXMgc2VlbXMgdG8gY29udGFpbiBjb2RlIGxpa2UKIC8vICAgVCB0KGEpOwogLy8gICBhID0gYjsKIC8vICAgYiA9IHQ7CiAvLyBpbnN0ZWFkIG9mIHVzaW5nIHN3YXAuIFRoaXMgaXMgdGhlIHJlYXNvbiBmb3IgdGhlCiAvLyBzdHJhbmdlIGNvcHkgY29uc3RydWN0b3IuCiBzb3J0KGJlZ2luKHNvcnRlZCksIGVuZChzb3J0ZWQpLAogICAgICBncmVhdGVyPGludD57fSk7CgogY29weShiZWdpbihzb3J0ZWQpLCBlbmQoc29ydGVkKSwKICAgICAgb3N0cmVhbV9pdGVyYXRvcjxpbnQ+e2NvdXQsICIsICJ9KTsKIGNvdXQgPDwgZW5kbDsKCiBjb3B5KGJlZ2luKGlucHV0KSwgZW5kKGlucHV0KSwKICAgICAgb3N0cmVhbV9pdGVyYXRvcjxpbnQ+e2NvdXQsICIsICJ9KTsKIGNvdXQgPDwgZW5kbDsKIHJldHVybiAwOwp9
1, 3, 5, 7, 9,
copied 0x9456a18:3 to 0x9456a88
0x9456a18:3 overwritten with 0x9456a10:1
0x9456a10:1 overwritten with 0x9456a88:3
freed 0x9456a88:3
copied 0x9456a20:5 to 0x9456a88
0x9456a20:5 overwritten with 0x9456a18:1
0x9456a18:1 overwritten with 0x9456a10:3
0x9456a10:3 overwritten with 0x9456a88:5
freed 0x9456a88:5
copied 0x9456a28:7 to 0x9456a88
0x9456a28:7 overwritten with 0x9456a20:1
0x9456a20:1 overwritten with 0x9456a18:3
0x9456a18:3 overwritten with 0x9456a10:5
0x9456a10:5 overwritten with 0x9456a88:7
freed 0x9456a88:7
copied 0x9456a30:9 to 0x9456a88
0x9456a30:9 overwritten with 0x9456a28:1
0x9456a28:1 overwritten with 0x9456a20:3
0x9456a20:3 overwritten with 0x9456a18:5
0x9456a18:5 overwritten with 0x9456a10:7
0x9456a10:7 overwritten with 0x9456a88:9
freed 0x9456a88:9
9, 7, 5, 3, 1,
9, 2, 7, 4, 5, 6, 3, 8, 1,