Feature #1453
Explore use of adaptive rvalue/lvalue argument passing
Status: | New | Start date: | 03/25/2013 | |
---|---|---|---|---|
Priority: | Low | Due 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_; };