#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;
}