Template Class RValueRef#

Class Documentation#

template<typename TObjRef, typename = std::enable_if_t<std::is_base_of_v<ObjectRef, TObjRef>>>
class RValueRef#

Helper class to define rvalue reference type.

By default, FFI pass all values by lvalue reference.

However, we do allow users to intentionally mark a function parameter as RValueRef<T>. In such cases, the caller can choose to pass parameter wrapped by RValueRef<T> to the function. In which case the parameter can be directly moved by the callee. The caller can also choose to pass a normal lvalue to the function, in such case a copy will be triggered.

To keep FFI checking overhead minimal, we do not handle case when rvalue is passed, but the callee did not declare the parameter as RValueRef<T>.

This design allows us to still leverage move semantics for parameters that need copy on write scenarios (and requires an unique copy).

void Example() {
  auto append = Function::FromTyped([](RValueRef<Array<int>> ref, int val) -> Array<int> {
    Array<int> arr = *std::move(ref);
    assert(arr.unique());
    arr.push_back(val);
    return arr;
  });
  Array<int> a = Array<int>({1, 2});
  // as we use rvalue ref to move a into append
  // we keep a single copy of the Array without creating new copies during copy-on-write
  a = append(RvalueRef(std::move(a)), 3);
  assert(a.size() == 3);
}

Public Types

using ContainerType = typename TObjRef::ContainerType#

the container type of the rvalue ref

Public Functions

inline explicit RValueRef(TObjRef &&data)#

only allow move constructor from rvalue of T