felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=1c402f62a9ef61428ea236da8558b8dd8bcb76c5

commit 1c402f62a9ef61428ea236da8558b8dd8bcb76c5
Author: Felipe Magno de Almeida <[email protected]>
Date:   Tue Jul 5 16:31:35 2016 -0300

    eolian-cxx: Fix generation for ref generic_values and Eolian classes
---
 src/bindings/cxx/eina_cxx/eina_value.hh            | 264 +++++++++++++++------
 src/bindings/cxx/eo_cxx/eo_concrete.hh             |   4 -
 src/bindings/cxx/eo_cxx/eo_cxx_interop.hh          |  43 +++-
 src/lib/eo/eo_base.eo                              |   2 +-
 src/lib/eolian_cxx/grammar/c_type.hpp              |   2 +
 src/lib/eolian_cxx/grammar/converting_argument.hpp |   5 +-
 .../eolian_cxx/grammar/function_declaration.hpp    |   2 +-
 src/lib/eolian_cxx/grammar/function_definition.hpp |   6 +-
 src/lib/eolian_cxx/grammar/type_impl.hpp           |  15 +-
 9 files changed, 256 insertions(+), 87 deletions(-)

diff --git a/src/bindings/cxx/eina_cxx/eina_value.hh 
b/src/bindings/cxx/eina_cxx/eina_value.hh
index 0f348c1..947b5d4 100644
--- a/src/bindings/cxx/eina_cxx/eina_value.hh
+++ b/src/bindings/cxx/eina_cxx/eina_value.hh
@@ -304,15 +304,15 @@ struct _eina_value_traits<T[], typename 
eina::enable_if<eina::is_pod<T>::value>:
   }
 };
 
-class value;
+class value_view;
 
 template <typename T>
-T get(value const& v);
+T get(value_view const& v);
 
 /**
  * Store generic value
  */
-class value
+class value_view
 {
   /**
    * @brief Initialize the <tt>eina::value</tt> with the given argument.
@@ -329,8 +329,8 @@ public:
   /**
    * @brief Default constructor. Create an empty generic value storage.
    */
-  value()
-    : _raw(_eina_value_traits<char>::create())
+  value_view()
+    : _raw(nullptr)
   {
   }
 
@@ -339,7 +339,7 @@ public:
    * @param v Value to be stored.
    */
   template <typename T>
-  value(T v, typename 
std::enable_if<_eina_value_traits<T>::is_specialized::value>::type* = 0)
+  value_view(T v, typename 
std::enable_if<_eina_value_traits<T>::is_specialized::value>::type* = 0)
   {
     primitive_init(v);
   }
@@ -348,7 +348,7 @@ public:
    * @brief Create an generic value storage holding a @c char value.
    * @param v @c char value to be stored.
    */
-  value(char v)
+  value_view(char v)
   {
     primitive_init(v);
   }
@@ -357,7 +357,7 @@ public:
    * @brief Create an generic value storage holding a @c short value.
    * @param v @c short value to be stored.
    */
-  value(short v)
+  value_view(short v)
   {
     primitive_init(v);
   }
@@ -366,7 +366,7 @@ public:
    * @brief Create an generic value storage holding a @c int value.
    * @param v @c int value to be stored.
    */
-  value(int v)
+  value_view(int v)
   {
     primitive_init(v);
   }
@@ -375,7 +375,7 @@ public:
    * @brief Create an generic value storage holding a @c long value.
    * @param v @c long value to be stored.
    */
-  value(long v)
+  value_view(long v)
   {
     primitive_init(v);
   }
@@ -384,7 +384,7 @@ public:
    * @brief Create an generic value storage holding a <tt>unsigned char</tt> 
value.
    * @param v <tt>unsigned char</tt> value to be stored.
    */
-  value(unsigned char v)
+  value_view(unsigned char v)
   {
     primitive_init(v);
   }
@@ -393,7 +393,7 @@ public:
    * @brief Create an generic value storage holding a <tt>unsigned short</tt> 
value.
    * @param v <tt>unsigned short</tt> value to be stored.
    */
-  value(unsigned short v)
+  value_view(unsigned short v)
   {
     primitive_init(v);
   }
@@ -402,7 +402,7 @@ public:
    * @brief Create an generic value storage holding a <tt>unsigned int</tt> 
value.
    * @param v <tt>unsigned int</tt> value to be stored.
    */
-  value(unsigned int v)
+  value_view(unsigned int v)
   {
     primitive_init(v);
   }
@@ -411,7 +411,7 @@ public:
    * @brief Create an generic value storage holding a <tt>unsigned long</tt> 
value.
    * @param v <tt>unsigned long</tt> value to be stored.
    */
-  value(unsigned long v)
+  value_view(unsigned long v)
   {
     primitive_init(v);
   }
@@ -420,7 +420,7 @@ public:
    * @brief Create an generic value storage holding a @c float value.
    * @param v @c float value to be stored.
    */
-  value(float v)
+  value_view(float v)
   {
     primitive_init(v);
   }
@@ -429,54 +429,19 @@ public:
    * @brief Create an generic value storage holding a @c double value.
    * @param v @c double value to be stored.
    */
-  value(double v)
+  value_view(double v)
   {
     primitive_init(v);
   }
 
-  /**
-   * @brief Deallocate stored value.
-   */
-  ~value()
-  {
-    eina_value_free(_raw);
-  }
-
-  value(Eina_Value* raw)
+  value_view(Eina_Value* raw)
     : _raw(raw) {}
 
   /**
-   * @brief Copy Constructor. Create an generic value storage holding the same 
value of @p other.
-   * @param other Another <tt>eina::value</tt> object.
-   */
-  value(value const& other)
-    : _raw(_eina_value_traits<char>::create())
-  {
-    if(!eina_value_copy(const_cast<Eina_Value const*>(other._raw), _raw))
-      {
-         EFL_CXX_THROW(eina::system_error(eina::get_error_code()));
-      }
-  }
-
-  /**
-   * @brief Assignment operator. Replace the current stored value by the value 
in @p other.
-   * @param other Another <tt>eina::value</tt> object.
-   */
-  value& operator=(value const& other)
-  {
-    eina_value_flush(_raw);
-    if(!eina_value_copy(const_cast<Eina_Value const*>(other._raw), _raw))
-      {
-         EFL_CXX_THROW(eina::system_error(eina::get_error_code()));
-      }
-    return *this;
-  }
-
-  /**
    * @brief Swap stored values with the given <tt>eina::value</tt> object.
    * @param other Another <tt>eina::value</tt> object.
    */
-  void swap(value& other)
+  void swap(value_view& other)
   {
     std::swap(_raw, other._raw);
   }
@@ -511,7 +476,7 @@ public:
   {
     return ::eina_value_type_get(_raw);
   }
-private:
+protected:
   ::Eina_Value* _raw;
 
   /**
@@ -530,7 +495,7 @@ private:
    * match the current stored value type.
    */
   template <typename T>
-  friend T get(value const& v)
+  friend T get(value_view const& v)
   {
     return _eina_value_traits<T>::get(v._raw);
   }
@@ -541,7 +506,7 @@ private:
  * @param lhs First <tt>eina::value</tt> object.
  * @param rhs Second <tt>eina::value</tt> object.
  */
-inline void swap(value& lhs, value& rhs)
+inline void swap(value_view& lhs, value_view& rhs)
 {
   lhs.swap(rhs);
 }
@@ -553,7 +518,7 @@ inline void swap(value& lhs, value& rhs)
  * @return @c true if the stored values are of the same type and equals
  *         in content, @c false otherwise.
  */
-inline bool operator==(value const& lhs, value const& rhs)
+inline bool operator==(value_view const& lhs, value_view const& rhs)
 {
   return lhs.type_info() == rhs.type_info()
     && eina_value_compare(lhs.native_handle(), rhs.native_handle()) == 0;
@@ -569,7 +534,7 @@ inline bool operator==(value const& lhs, value const& rhs)
  *         type identifier of @p lhs comes before the type indentifier
  *         of @p rhs. Returns @c false in all other cases.
  */
-inline bool operator<(value const& lhs, value const& rhs)
+inline bool operator<(value_view const& lhs, value_view const& rhs)
 {
   return std::less<Eina_Value_Type const*>()(lhs.type_info(), rhs.type_info())
     || (lhs.type_info() == rhs.type_info()
@@ -577,16 +542,16 @@ inline bool operator<(value const& lhs, value const& rhs)
 }
 
 /**
- * @brief More than comparison between two <tt>eina::value</tt> objects.
- * @param lhs <tt>eina::value</tt> object at the left side of the expression.
- * @param rhs <tt>eina::value</tt> object at the right side of the expression.
+ * @brief More than comparison between two <tt>eina::value_view</tt> objects.
+ * @param lhs <tt>eina::value_view</tt> object at the left side of the 
expression.
+ * @param rhs <tt>eina::value_view</tt> object at the right side of the 
expression.
  * @return For objects holding values of the same type, returns @c true
  *         if @p lhs value is more than @p rhs value. For objects
  *         holding values of different types, returns @c true if the
  *         type identifier of @p lhs comes after the type indentifier
  *         of @p rhs. Returns @c false in all other cases.
  */
-inline bool operator>(value const& lhs, value const& rhs)
+inline bool operator>(value_view const& lhs, value_view const& rhs)
 {
   return std::less<Eina_Value_Type const*>()(rhs.type_info(), lhs.type_info())
     || (rhs.type_info() == lhs.type_info()
@@ -594,16 +559,16 @@ inline bool operator>(value const& lhs, value const& rhs)
 }
 
 /**
- * @brief Less than or equal comparison between two <tt>eina::value</tt> 
objects.
- * @param lhs <tt>eina::value</tt> object at the left side of the expression.
- * @param rhs <tt>eina::value</tt> object at the right side of the expression.
+ * @brief Less than or equal comparison between two <tt>eina::value_view</tt> 
objects.
+ * @param lhs <tt>eina::value_view</tt> object at the left side of the 
expression.
+ * @param rhs <tt>eina::value_view</tt> object at the right side of the 
expression.
  * @return For objects holding values of the same type, returns @c true
  *         if @p lhs value is less than or equal to @p rhs value. For
  *         objects holding values of different types, returns @c true if
  *         the type identifier of @p lhs comes before the type
  *         indentifier of @p rhs. Returns @c false in all other cases.
  */
-inline bool operator<=(value const& lhs, value const& rhs)
+inline bool operator<=(value_view const& lhs, value_view const& rhs)
 {
   return !(lhs > rhs);
 }
@@ -618,7 +583,7 @@ inline bool operator<=(value const& lhs, value const& rhs)
  *         the type identifier of @p lhs comes after the type
  *         indentifier of @p rhs. Returns @c false in all other cases.
  */
-inline bool operator>=(value const& lhs, value const& rhs)
+inline bool operator>=(value_view const& lhs, value_view const& rhs)
 {
   return !(lhs < rhs);
 }
@@ -631,12 +596,175 @@ inline bool operator>=(value const& lhs, value const& 
rhs)
  *         @p lhs is different from the value of @rhs, @c false
  *         otherwise.
  */
-inline bool operator!=(value const& lhs, value const& rhs)
+inline bool operator!=(value_view const& lhs, value_view const& rhs)
 {
   return !(lhs == rhs);
 }
 
 /**
+ * Store generic value
+ */
+struct value :  value_view
+{
+   using value_view::value_view;
+
+   value(std::nullptr_t) {}
+   value() : value_view(_eina_value_traits<char>::create()) {}
+   explicit value(Eina_Value* raw)
+     : value_view(raw) {}
+
+   value(Eina_Value const* raw)
+     : value_view(_eina_value_traits<char>::create())
+   {
+     if(!eina_value_copy(raw, _raw))
+       {
+          eina_value_free(_raw);
+          EFL_CXX_THROW(eina::system_error(eina::get_error_code()));
+       }
+   }
+  
+   /**
+    * @brief Deallocate stored value.
+    */
+   ~value()
+   {
+      if(_raw)
+        eina_value_free(_raw);
+   }
+
+   /**
+    * @brief Copy Constructor. Create an generic value storage holding the 
same value of @p other.
+    * @param other Another <tt>eina::value</tt> object.
+    */
+   value(value_view const& other)
+     : value_view(_eina_value_traits<char>::create())
+   {
+     if(!eina_value_copy(other.native_handle(), _raw))
+       {
+          eina_value_free(_raw);
+          EFL_CXX_THROW(eina::system_error(eina::get_error_code()));
+       }
+   }
+
+   /**
+    * @brief Assignment operator. Replace the current stored value by the 
value in @p other.
+    * @param other Another <tt>eina::value</tt> object.
+    */
+   value& operator=(value other)
+   {
+     other.swap(*this);
+     return *this;
+   }
+
+   void swap(value& other)
+   {
+     _base_get(other).swap(*this);
+   }
+private:
+   static value_view& _base_get(value& v) { return v; }
+   static value_view const& _base_get(value const& v) { return v; }
+   /**
+    * @brief Swap the stored values between the given <tt>eina::value</tt> 
objects.
+    * @param lhs First <tt>eina::value</tt> object.
+    * @param rhs Second <tt>eina::value</tt> object.
+    */
+   friend inline void swap(value& lhs, value& rhs)
+   {
+     lhs.swap(rhs);
+   }
+
+   /**
+    * @brief Compare if the stored values are equal.
+    * @param lhs <tt>eina::value</tt> object at the left side of the 
expression.
+    * @param rhs <tt>eina::value</tt> object at the right side of the 
expression.
+    * @return @c true if the stored values are of the same type and equals
+    *         in content, @c false otherwise.
+    */
+   friend inline bool operator==(value const& lhs, value const& rhs)
+   {
+      return _base_get(lhs) == _base_get(rhs);
+   }
+
+   /**
+    * @brief Less than comparison between two <tt>eina::value</tt> objects.
+    * @param lhs <tt>eina::value</tt> object at the left side of the 
expression.
+    * @param rhs <tt>eina::value</tt> object at the right side of the 
expression.
+    * @return For objects holding values of the same type, returns @c true
+    *         if @p lhs value is less than @p rhs value. For objects
+    *         holding values of different types, returns @c true if the
+    *         type identifier of @p lhs comes before the type indentifier
+    *         of @p rhs. Returns @c false in all other cases.
+    */
+   friend inline bool operator<(value const& lhs, value const& rhs)
+   {
+      return _base_get(lhs) < _base_get(rhs);
+   }
+
+   /**
+    * @brief More than comparison between two <tt>eina::value</tt> objects.
+    * @param lhs <tt>eina::value</tt> object at the left side of the 
expression.
+    * @param rhs <tt>eina::value</tt> object at the right side of the 
expression.
+    * @return For objects holding values of the same type, returns @c true
+    *         if @p lhs value is more than @p rhs value. For objects
+    *         holding values of different types, returns @c true if the
+    *         type identifier of @p lhs comes after the type indentifier
+    *         of @p rhs. Returns @c false in all other cases.
+    */
+   friend inline bool operator>(value const& lhs, value const& rhs)
+   {
+      return _base_get(lhs) > _base_get(rhs);
+   }
+
+   /**
+    * @brief Less than or equal comparison between two <tt>eina::value</tt> 
objects.
+    * @param lhs <tt>eina::value</tt> object at the left side of the 
expression.
+    * @param rhs <tt>eina::value</tt> object at the right side of the 
expression.
+    * @return For objects holding values of the same type, returns @c true
+    *         if @p lhs value is less than or equal to @p rhs value. For
+    *         objects holding values of different types, returns @c true if
+    *         the type identifier of @p lhs comes before the type
+    *         indentifier of @p rhs. Returns @c false in all other cases.
+    */
+   friend inline bool operator<=(value const& lhs, value const& rhs)
+   {
+     return _base_get(lhs) <= _base_get(rhs);
+   }
+
+   /**
+    * @brief More than or equal comparison between two <tt>eina::value</tt> 
objects.
+    * @param lhs <tt>eina::value</tt> object at the left side of the 
expression.
+    * @param rhs <tt>eina::value</tt> object at the right side of the 
expression.
+    * @return For objects holding values of the same type, returns @c true
+    *         if @p lhs value is more than or equal to @p rhs value. For
+    *         objects holding values of different types, returns @c true if
+    *         the type identifier of @p lhs comes after the type
+    *         indentifier of @p rhs. Returns @c false in all other cases.
+    */
+   friend inline bool operator>=(value const& lhs, value const& rhs)
+   {
+      return _base_get(lhs) >= _base_get(rhs);
+   }
+
+   /**
+    * @brief Compare if the stored values are different.
+    * @param lhs <tt>eina::value</tt> object at the left side of the 
expression.
+    * @param rhs <tt>eina::value</tt> object at the right side of the 
expression.
+    * @return @c true if the value types are different or if the value of
+    *         @p lhs is different from the value of @rhs, @c false
+    *         otherwise.
+    */
+   friend inline bool operator!=(value const& lhs, value const& rhs)
+   {
+      return _base_get(lhs) != _base_get(rhs);
+   }
+};
+
+static_assert(std::is_standard_layout<value>::value, "");
+static_assert(std::is_standard_layout<value_view>::value, "");
+static_assert(sizeof(value) == sizeof(Eina_Value*), "");
+static_assert(sizeof(value_view) == sizeof(Eina_Value*), "");
+    
+/**
  * @}
  */
 
diff --git a/src/bindings/cxx/eo_cxx/eo_concrete.hh 
b/src/bindings/cxx/eo_cxx/eo_concrete.hh
index 11d2c5b..8b97827 100644
--- a/src/bindings/cxx/eo_cxx/eo_concrete.hh
+++ b/src/bindings/cxx/eo_cxx/eo_concrete.hh
@@ -211,10 +211,6 @@ template <typename T>
 struct is_eolian_object : std::false_type {};
 template <typename T>
 struct is_eolian_object<T const> : is_eolian_object<T> {};
-template <typename T>
-struct is_eolian_object<T const&> : is_eolian_object<T> {};
-template <typename T>
-struct is_eolian_object<T&> : is_eolian_object<T> {};
 template <>
 struct is_eolian_object<eo::concrete> : std::true_type {};
     
diff --git a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh 
b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
index 570f5c8..3e8c48b 100644
--- a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
@@ -64,6 +64,13 @@ struct inout_traits<void> { typedef void* type; };
 template <typename T>
 struct inout_traits<efl::eina::future<T>> { typedef efl::eina::future<T>& 
type; };
 
+template <typename T>
+struct return_traits { typedef T type; };
+template <>
+struct return_traits<eina::value_view&> { typedef eina::value_view type; };
+template <>
+struct return_traits<eina::value_view const&> { typedef eina::value_view type; 
};
+
 template <typename To, typename From, bool Own = false, typename Lhs, typename 
Rhs>
 void assign_out(Lhs& lhs, Rhs& rhs);
   
@@ -151,7 +158,17 @@ void assign_out_impl(efl::eina::optional<T>& lhs, Rhs& 
rhs, tag<efl::eina::optio
     assign_out<U&, O, true>(*lhs, rhs);
 }
 template <typename Tag>
-void assign_out_impl(eina::value& lhs, Eina_Value const& rhs, Tag)
+void assign_out_impl(eina::value& lhs, Eina_Value& rhs, Tag)
+{
+  Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_CHAR);
+  eina_value_flush(v);
+  eina_value_copy(&rhs, v);
+  lhs = {v};
+  eina_value_flush(&rhs);
+}
+// This is a invalid use-case that is used in EFL. This leaks
+template <typename Tag>
+void assign_out_impl(eina::value_view& lhs, Eina_Value& rhs, Tag)
 {
   Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_CHAR);
   eina_value_flush(v);
@@ -324,6 +341,12 @@ Eo const* convert_to_c_impl(T v, tag<Eo const*, T>
 {
   return const_cast<Eo const*>(v._eo_ptr());
 }
+template <typename T>
+Eo** convert_to_c_impl(T& v, tag<Eo**, T&>
+                       , typename 
std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
+{
+  return reinterpret_cast<Eo**>(static_cast<void*>(&v));
+}
 inline const char* convert_to_c_impl( ::efl::eina::string_view v, tag<const 
char*, ::efl::eina::string_view>)
 {
   return v.c_str();
@@ -355,12 +378,24 @@ inline Eina_Value* convert_to_c_impl( ::efl::eina::value 
v, tag<Eina_Value*, in_
   eina_value_copy(v.native_handle(), nv);
   return nv;
 }
-inline Eina_Value const* convert_to_c_impl( ::efl::eina::value v, 
tag<Eina_Value const*, in_traits<eina::value>::type>)
+inline Eina_Value const* convert_to_c_impl( ::efl::eina::value& v, 
tag<Eina_Value const*, in_traits<eina::value>::type>)
 {
   Eina_Value* nv = eina_value_new(v.type_info());
   eina_value_copy(v.native_handle(), nv);
   return nv;
 }
+inline Eina_Value const* convert_to_c_impl( ::efl::eina::value_view const& v, 
tag<Eina_Value const*, in_traits<eina::value_view const&>::type>)
+{
+  return v.native_handle();
+}
+inline Eina_Value* convert_to_c_impl( ::efl::eina::value_view& v, 
tag<Eina_Value*, in_traits<eina::value_view&>::type>)
+{
+  return v.native_handle();
+}
+inline Eina_Value* convert_to_c_impl( ::efl::eina::value_view const& v, 
tag<Eina_Value*, in_traits<eina::value_view const&>::type>)
+{
+  return const_cast<Eina_Value*>(v.native_handle());
+}
 inline Eina_Bool convert_to_c_impl( bool b, tag<Eina_Bool, bool>)
 {
   return b;
@@ -632,6 +667,10 @@ inline efl::eina::value convert_to_return(Eina_Value* 
value, tag<Eina_Value*, ef
 {
   return efl::eina::value{value};
 }
+inline efl::eina::value_view convert_to_return(Eina_Value* value, 
tag<Eina_Value*, efl::eina::value_view>)
+{
+  return efl::eina::value_view{value};
+}
 template <typename T, typename U>
 T convert_to_return(U* value, tag<T, U*>, typename 
std::enable_if<is_range<T>::value || is_container<T>::value>::type* = 0)
 {
diff --git a/src/lib/eo/eo_base.eo b/src/lib/eo/eo_base.eo
index ce56715..72d7906 100644
--- a/src/lib/eo/eo_base.eo
+++ b/src/lib/eo/eo_base.eo
@@ -200,7 +200,7 @@ abstract Eo.Base ()
            being freed.
          ]]
          params {
-            @out wref: Eo.Base;
+            @in wref: ref(Eo.Base);
          }
       }
       wref_del {
diff --git a/src/lib/eolian_cxx/grammar/c_type.hpp 
b/src/lib/eolian_cxx/grammar/c_type.hpp
index 54b996d..6d814f8 100644
--- a/src/lib/eolian_cxx/grammar/c_type.hpp
+++ b/src/lib/eolian_cxx/grammar/c_type.hpp
@@ -19,6 +19,8 @@ struct c_type_visitor
                 , std::make_tuple(name.namespaces, name.eolian_name
                                   , std::string{name.base_qualifier & 
qualifier_info::is_const ? " const" : ""})
                 , context_null {});
+    if(name.base_qualifier & qualifier_info::is_ref)
+      n += '*';
     return n;
   }
   template <typename T>
diff --git a/src/lib/eolian_cxx/grammar/converting_argument.hpp 
b/src/lib/eolian_cxx/grammar/converting_argument.hpp
index 3b5cb1d..cb3f750 100644
--- a/src/lib/eolian_cxx/grammar/converting_argument.hpp
+++ b/src/lib/eolian_cxx/grammar/converting_argument.hpp
@@ -25,9 +25,10 @@ struct converting_argument_generator
      attributes::qualifier_def qualifier = 
param.type.original_type.visit(attributes::get_qualifier_visitor{});
      return as_generator
        (
-        attribute_reorder<1, -1, 2>
+        attribute_reorder<-1, -1, 2>
         (
-         " ::efl::eolian::convert_to_c<" << c_type << ", " << parameter_type
+         " ::efl::eolian::convert_to_c<" << c_type
+         << ", " << parameter_type
          << (qualifier & qualifier_info::is_own
              ? ", true" : "")
          << ">(" << string << ")"
diff --git a/src/lib/eolian_cxx/grammar/function_declaration.hpp 
b/src/lib/eolian_cxx/grammar/function_declaration.hpp
index f01c214..6e124df 100644
--- a/src/lib/eolian_cxx/grammar/function_declaration.hpp
+++ b/src/lib/eolian_cxx/grammar/function_declaration.hpp
@@ -19,7 +19,7 @@ struct function_declaration_generator
   bool generate(OutputIterator sink, attributes::function_def const& f, 
Context const& context) const
   {
     return as_generator
-      (grammar::type(true) << " " << string << "(" << (parameter % ", ") << ") 
const;\n")
+      ("::efl::eolian::return_traits<" << grammar::type(true) << ">::type " << 
string << "(" << (parameter % ", ") << ") const;\n")
       .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), 
f.parameters), context);
   }
 };
diff --git a/src/lib/eolian_cxx/grammar/function_definition.hpp 
b/src/lib/eolian_cxx/grammar/function_definition.hpp
index a2de1aa..714cb1f 100644
--- a/src/lib/eolian_cxx/grammar/function_definition.hpp
+++ b/src/lib/eolian_cxx/grammar/function_definition.hpp
@@ -54,7 +54,7 @@ struct function_definition_generator
         return false;
      
       if(!as_generator
-         ("inline " << grammar::type(true) << " " << string << "::" << string 
<< "(" << (parameter % ", ") << ") const\n{\n")
+         ("inline ::efl::eolian::return_traits<" << grammar::type(true) << 
">::type " << string << "::" << string << "(" << (parameter % ", ") << ") 
const\n{\n")
          .generate(sink, std::make_tuple(f.return_type, 
_klass_name.eolian_name, escape_keyword(f.name), f.parameters), ctx))
         return false;
 
@@ -133,8 +133,8 @@ struct function_definition_generator
          .generate(sink, f.parameters, ctx)) return false;
       
       if(f.return_type != attributes::void_
-         && !as_generator(scope_tab << "return 
::efl::eolian::convert_to_return<"
-                          << type(true) << ">(__return_value);\n"
+         && !as_generator(scope_tab << "return 
::efl::eolian::convert_to_return< ::efl::eolian::return_traits<"
+                          << type(true) << ">::type>(__return_value);\n"
                           ).generate(sink, f.return_type, ctx)) return false;
 
       if(!as_generator("}\n").generate(sink, attributes::unused, ctx))
diff --git a/src/lib/eolian_cxx/grammar/type_impl.hpp 
b/src/lib/eolian_cxx/grammar/type_impl.hpp
index 3e67d85..6e18b2b 100644
--- a/src/lib/eolian_cxx/grammar/type_impl.hpp
+++ b/src/lib/eolian_cxx/grammar/type_impl.hpp
@@ -102,9 +102,12 @@ struct visitor_generate
                 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
                 return replace_base_type(r, " ::efl::eina::stringshare");
               }}
-           , {"generic_value", nullptr, [&]
+           , {"generic_value", true, [&]
               { return regular_type_def{" ::efl::eina::value", 
regular.base_qualifier, {}};
               }}
+           , {"generic_value", false, [&]
+              { return regular_type_def{" ::efl::eina::value_view", 
regular.base_qualifier, {}};
+              }}
         };
       if(regular.base_type == "void_ptr")
         {
@@ -207,11 +210,11 @@ struct visitor_generate
    }
    bool operator()(attributes::klass_name klass) const
    {
-     if(as_generator(" " << *("::" << lower_case[string]) << "::" << string)
-        .generate(sink, 
std::make_tuple(attributes::cpp_namespaces(klass.namespaces), 
klass.eolian_name), *context))
-       return true;
-     else
-       return false;
+     return
+       as_generator(" " << *("::" << lower_case[string]) << "::" << string)
+       .generate(sink, 
std::make_tuple(attributes::cpp_namespaces(klass.namespaces), 
klass.eolian_name), *context)
+       && (!(klass.base_qualifier & qualifier_info::is_ref)
+           || as_generator("&").generate(sink, attributes::unused, *context));
    }
    bool operator()(attributes::complex_type_def const& complex) const
    {

-- 


Reply via email to