Skip to content
Snippets Groups Projects
rvref.hh 1.39 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef __VEREIGN_CORE_RVREF_HH
    #define __VEREIGN_CORE_RVREF_HH
    
    namespace vereign {
    namespace core {
    
    #ifdef __WINDOWS__
    #pragma warning(push)
    #pragma warning(disable: 4521)
    #endif
    
    /**
     * Rvalue reference wrapper.
     *
     * Wraps rvalue reference in copyable object.
     * Thus allowing lambda to capture rvalue references.
     *
     * @code
     * std::string foo = "foo";
     * auto foo_ref MakeRvRef(foo);
     * auto lambda = [foo_ref] () mutable {
     *   std::cout << foo_ref.get() << std::endl;
     * };
     * lambda();
     * @endcode
     *
     */
    template <typename T>
    class RvRef {
    public:
      RvRef() = delete;
      RvRef& operator=(RvRef& other) = delete;
    
      RvRef(T&& value) : value_{std::move(value)} {}
      RvRef(RvRef& other) : value_{std::move(other.value_)} {}
      RvRef(RvRef&& other) : value_{std::move(other.value_)} {}
    
      /**
       * Retrieve reference to the stored value.
       */
      const T& Get() const noexcept {
        return value_;
      }
    
      /**
       * Retrieve reference to the stored value.
       */
      T& Get() noexcept {
        return value_;
      }
    
      /**
       * Retrieve reference to the stored value.
       */
      const T* operator->() const noexcept {
        return &value_;
      }
    
      /**
       * Retrieve reference to the stored value.
       */
      T* operator->() noexcept {
        return &value_;
      }
    
    private:
      T value_;
    };
    
    #ifdef __WINDOWS__
    #pragma warning(pop)
    #endif
    
    template <typename T>
    RvRef<T> MakeRvRef(T&& value) {
      return RvRef<T>(std::move(value));
    }
    
    }
    }
    
    #endif