Feature #1453

Explore use of adaptive rvalue/lvalue argument passing

Added by M. Rolf about 11 years ago.

Status:NewStart date:03/25/2013
Priority:LowDue date:
Assignee:M. Rolf% Done:

0%

Category:-
Target version:NemoMath 0.5

Description

See http://codesynthesis.com/~boris/blog/2012/06/26/efficient-argument-passing-cxx11-part2

For instance

matrix operator+ (in<matrix> x, in<matrix> y)
{
  matrix&& x1 = x.rvalue () ? x.rget () :
                y.rvalue () ? y.rget () : matrix (x);
  const matrix& y1 = x.rvalue () ? y :
                     y.rvalue () ? x : y;
  x1 += y1;
  return std::move (x1);
}

... using ...

#include <type_traits>

template <typename T>
struct in
{
  in (const T& l): lv_ (&l), rv_ (0) {}
  in (T&& r): lv_ (0), rv_ (&r) {}

  // Accessors.
  //
  bool lvalue () const {return lv_ != 0;}
  bool rvalue () const {return rv_ != 0;}

  operator const T& () const {return get ();}
  const T& get () const {return lv_ ? *lv_ : *rv_;}
  T&& rget () const {return *rv_;}

  // Move. Returns a copy if lvalue.
  //
  T move () const {return lv_ ? *lv_ : std::move (*rv_);}

  // Support for implicit conversion via perfect forwarding.
  //
  typedef std::aligned_storage<sizeof (T), alignof (T)> storage;

  template <typename T1,
            typename std::enable_if<
              std::is_convertible<T1, T>::value, int>::type = 0>
  in (T1&& x, storage s = storage ())
      : lv_ (0), rv_ (new (&s) T (x)) {}

  in (T& l): lv_ (&l), rv_ (0) {} // For T1&& becoming T1&.

private:
  const T* lv_;
  T* rv_;
};

Also available in: Atom PDF