#ifndef DOSSIER_MOVE_BY_COPY_H
#define DOSSIER_MOVE_BY_COPY_H

#include <utility>
namespace util {
/*
 * When a copy is made, it moves the object
 * This allows you to move an object when a move can't be done.
 */
template<class T>
class MoveByCopy {
public:
  typedef T move_type;
private:
  move_type _to_move;
public:

  explicit MoveByCopy(move_type &&to_move) : _to_move(std::move(to_move)) { }

  MoveByCopy(MoveByCopy &&other) = default;
  
  MoveByCopy(const MoveByCopy &other) {
    *this = other;
  }

  MoveByCopy& operator=(MoveByCopy &&other) = default;
  
  MoveByCopy& operator=(const MoveByCopy &other) {
    this->_to_move = std::move(const_cast<MoveByCopy&>(other)._to_move);
    
    return *this;
  }

  operator move_type() {
    return std::move(_to_move);
  }
};

template<class T>
MoveByCopy<T> cmove(T &movable) {
  return MoveByCopy<T>(std::move(movable));
}

// Do NOT use this unless you are absolutely certain the object to be moved is no longer used by the caller
template<class T>
MoveByCopy<T> const_cmove(const T &movable) {
  return MoveByCopy<T>(std::move(const_cast<T&>(movable)));
}
}
#endif
