eolian_cxx: Using eina::optional to handle parameters without @nonull property
authorVitor Sousa <vitorsousasilva@gmail.com>
Mon, 5 Jan 2015 17:41:37 +0000 (15:41 -0200)
committerVitor Sousa <vitorsousasilva@gmail.com>
Mon, 5 Jan 2015 17:52:27 +0000 (15:52 -0200)
src/bin/eolian_cxx/eolian_wrappers.hh
src/bindings/eo_cxx/eo_cxx_interop.hh
src/lib/eolian_cxx/eo_types.hh
src/lib/eolian_cxx/grammar/type_generator.hh

index 4771739..d1b28a6 100644 (file)
@@ -359,6 +359,10 @@ parameter_type(Eolian_Function_Parameter const& parameter,
         if (!type.front().binding.empty())
           type.front().binding.insert(0, "const ");
      }
+   if (::eolian_parameter_is_nonull(&parameter))
+     {
+        type.is_nonull = true;
+     }
    return type;
 }
 
index ddf4375..ba6a473 100644 (file)
@@ -20,11 +20,27 @@ to_c(std::string const& x)
 }
 
 inline const char*
+to_c(eina::optional<std::string> const& x)
+{
+   if (!x)
+     return nullptr;
+   return x->c_str();
+}
+
+inline const char*
 to_c(efl::eina::stringshare const& x)
 {
    return x.c_str();
 }
 
+inline const char*
+to_c(eina::optional<efl::eina::stringshare> const& x)
+{
+   if (!x)
+     return nullptr;
+   return x->c_str();
+}
+
 inline Eina_Bool
 to_c(bool x)
 {
@@ -51,6 +67,14 @@ Eo* to_c(T const& v, typename std::enable_if<std::is_convertible<T*, ::efl::eo::
 }
 
 template <typename T>
+Eo* to_c(eina::optional<T> const& v, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
+{
+   if (!v)
+     return nullptr;
+   return v->_eo_ptr();
+}
+
+template <typename T>
 Eo** to_c(T* v, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
 {
    static_assert(sizeof(T) == sizeof(Eo*), "");
@@ -65,6 +89,15 @@ R to_native(T const& v)
 }
 
 template <typename R, typename T>
+R to_native(eina::optional<T> const& v)
+{
+   static_assert(sizeof(T) == sizeof(R), "");
+   if (!v)
+     return nullptr;
+   return v->native_handle();
+}
+
+template <typename R, typename T>
 R to_native(T* v)
 {
   static_assert(sizeof(T) == sizeof(typename std::remove_pointer<R>::type), "");
@@ -109,6 +142,24 @@ to_cxx(Eo* x, std::tuple<std::false_type>, tag<T>)
 }
 
 template <typename T>
+inline eina::optional<T>
+to_cxx(Eo* x, std::tuple<std::true_type>, tag<eina::optional<T> >)
+{
+   if (!x)
+     return nullptr;
+   return T(x);
+}
+
+template <typename T>
+inline eina::optional<T>
+to_cxx(Eo* x, std::tuple<std::false_type>, tag<eina::optional<T> >)
+{
+   if (!x)
+     return nullptr;
+   return T(::eo_ref(x));
+}
+
+template <typename T>
 inline T
 to_cxx(Eo** x, std::tuple<std::false_type>, tag<T>)
 {
@@ -137,6 +188,14 @@ to_cxx(const char* x, std::tuple<std::false_type>, tag<std::string>)
    return std::string(x);
 }
 
+inline eina::optional<std::string>
+to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::optional<std::string> >)
+{
+   if (!x)
+     return nullptr;
+   return std::string(x);
+}
+
 template <typename T, typename Enable = void>
 struct traits
 {
@@ -165,6 +224,15 @@ to_cxx(const Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina:
 }
 
 template <typename T, typename ...Args>
+inline eina::optional<efl::eina::range_list<T const> >
+to_cxx(const Eina_List* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::range_list<T> > >)
+{
+   if (!x)
+     return nullptr;
+   return efl::eina::range_list<T const> {x};
+}
+
+template <typename T, typename ...Args>
 inline efl::eina::range_list<T>
 to_cxx(Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_list<T> >)
 {
@@ -172,18 +240,44 @@ to_cxx(Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range
 }
 
 template <typename T, typename ...Args>
+inline eina::optional<efl::eina::range_list<T> >
+to_cxx(Eina_List* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::range_list<T> > >)
+{
+   if (!x)
+     return nullptr;
+   return efl::eina::range_list<T>{x};
+}
+
+template <typename T, typename ...Args>
 inline efl::eina::list<T>
 to_cxx(Eina_List* x, std::tuple<std::true_type, Args...>, tag< efl::eina::list<T> >)
 {
    return efl::eina::list<T> {x};
 }
 
+template <typename T, typename ...Args>
+inline eina::optional<efl::eina::list<T> >
+to_cxx(Eina_List* x, std::tuple<std::true_type, Args...>, tag< eina::optional<efl::eina::list<T> > >)
+{
+   if (!x)
+     return nullptr;
+   return efl::eina::list<T> {x};
+}
+
 inline eina::stringshare
 to_cxx(Eina_Stringshare const* x, const std::false_type, tag<eina::stringshare>)
 {
    return ::eina_stringshare_ref(x);
 }
 
+inline eina::optional<eina::stringshare>
+to_cxx(Eina_Stringshare const* x, const std::false_type, tag<eina::optional<eina::stringshare> >)
+{
+   if (!x)
+     return nullptr;
+   return eina::stringshare(::eina_stringshare_ref(x));
+}
+
 template <typename T, typename ...Args>
 inline efl::eina::accessor<T>
 to_cxx(Eina_Accessor* x, std::tuple<std::false_type, Args...>, tag< efl::eina::accessor<T> >)
@@ -192,6 +286,15 @@ to_cxx(Eina_Accessor* x, std::tuple<std::false_type, Args...>, tag< efl::eina::a
 }
 
 template <typename T, typename ...Args>
+inline eina::optional<efl::eina::accessor<T> >
+to_cxx(Eina_Accessor* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::accessor<T> > >)
+{
+   if (!x)
+     return nullptr;
+   return efl::eina::accessor<T>(x);
+}
+
+template <typename T, typename ...Args>
 inline efl::eina::iterator<T>
 to_cxx(Eina_Iterator* x, std::tuple<std::false_type, Args...>, tag< efl::eina::iterator<T> >)
 {
@@ -199,6 +302,15 @@ to_cxx(Eina_Iterator* x, std::tuple<std::false_type, Args...>, tag< efl::eina::i
 }
 
 template <typename T, typename ...Args>
+inline eina::optional<efl::eina::iterator<T> >
+to_cxx(Eina_Iterator* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::iterator<T> > >)
+{
+   if (!x)
+     return nullptr;
+   return efl::eina::iterator<T>(x);
+}
+
+template <typename T, typename ...Args>
 T
 to_cxx(Eo const* x, std::tuple<std::false_type, Args...>, tag< T >
        , typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
@@ -208,6 +320,17 @@ to_cxx(Eo const* x, std::tuple<std::false_type, Args...>, tag< T >
 }
 
 template <typename T, typename ...Args>
+eina::optional<T>
+to_cxx(Eo const* x, std::tuple<std::false_type, Args...>, tag< eina::optional<T> >
+       , typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
+{
+   // Workaround for erroneous constness
+   if (!x)
+     return nullptr;
+   return T{ ::eo_ref(const_cast<Eo*>(x))};
+}
+
+template <typename T, typename ...Args>
 T
 to_cxx(Eo const* x, std::tuple<std::true_type, Args...>, tag< T >
        , typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
@@ -216,6 +339,17 @@ to_cxx(Eo const* x, std::tuple<std::true_type, Args...>, tag< T >
    return T{const_cast<Eo*>(x)};
 }
 
+template <typename T, typename ...Args>
+eina::optional<T>
+to_cxx(Eo const* x, std::tuple<std::true_type, Args...>, tag< eina::optional<T> >
+       , typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
+{
+   // Workaround for erroneous constness
+   if (!x)
+     return nullptr;
+   return T{const_cast<Eo*>(x)};
+}
+
 template <typename T, typename U, typename O>
 T to_cxx(U object, O o)
 {
index 4fa79a4..42b034d 100644 (file)
@@ -80,17 +80,21 @@ struct eolian_type_instance
 {
   eolian_type_instance()
     : is_out(false)
+    , is_nonull(false)
     , parts()
   {}
 
   eolian_type_instance(std::initializer_list<eolian_type> il,
-                       bool is_out_ = false)
+                       bool is_out_ = false,
+                       bool is_nonull_ = false)
     : is_out(is_out_)
+    , is_nonull(is_nonull_)
     , parts(il)
   {}
 
   explicit eolian_type_instance(std::size_t size)
     : is_out(false)
+    , is_nonull(false)
     , parts(size)
   {}
 
@@ -101,6 +105,7 @@ struct eolian_type_instance
   eolian_type const& front() const { return parts.front(); }
 
   bool is_out;
+  bool is_nonull;
   eolian_type_container parts;
 };
 
@@ -145,6 +150,12 @@ type_is_class(eolian_type_instance const& type)
    return type_is_class(type.front());
 }
 
+inline bool
+type_is_nonull(eolian_type_instance const& type)
+{
+   return type.is_nonull;
+}
+
 inline eolian_type
 type_to_native(eolian_type const& type)
 {
index 2dc6681..5913330 100644 (file)
@@ -93,6 +93,8 @@ operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x)
 
    if (x._type.is_out && type_is_binding(x._type.front()))
      res += "*";
+   else if (!x._type.is_nonull && x._type.front().is_class)
+     res = "::efl::eina::optional< " + res + " >";
 
    return out << res;
 }