summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-09-07 18:02:43 +0900
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-09-08 11:47:29 +0900
commit48b3c127f7c4e7ffc7dbf66013c3ec2812ae9a5f (patch)
tree30f2a04e2b8ae4fa69e700bc1103a8ea4aaba31b
parentff96e30c7239118b349883f8b1b882e9c64d10c5 (diff)
downloadefl-48b3c127f7c4e7ffc7dbf66013c3ec2812ae9a5f.tar.gz
eo-cxx: Require instantiate keyword for constructors calling efl_add to avoid ambiguity
-rw-r--r--src/bindings/cxx/eo_cxx/eo_concrete.hh3
-rw-r--r--src/bindings/cxx/eo_cxx/eo_cxx_interop.hh14
-rw-r--r--src/examples/elementary/Makefile.am2
-rw-r--r--src/examples/elementary/toolbar_cxx_example_01.cc135
-rw-r--r--src/lib/eolian_cxx/grammar/class_declaration.hpp12
-rw-r--r--src/lib/eolian_cxx/grammar/class_definition.hpp37
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_iterator.cc8
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_test_binding.cc14
8 files changed, 200 insertions, 25 deletions
diff --git a/src/bindings/cxx/eo_cxx/eo_concrete.hh b/src/bindings/cxx/eo_cxx/eo_concrete.hh
index 8b978275b9..f02eb0cba0 100644
--- a/src/bindings/cxx/eo_cxx/eo_concrete.hh
+++ b/src/bindings/cxx/eo_cxx/eo_concrete.hh
@@ -31,6 +31,8 @@ namespace efl { namespace eo {
/// @addtogroup Efl_Cxx_API
/// @{
+struct instantiate_t {} const instantiate = {};
+
/// @brief Creates concrete versions for <em>Eo</em> wrappers.
///
/// This class creates the concrete version of all C++ <em>Eo</em> wrappers.
@@ -77,7 +79,6 @@ struct concrete
concrete(concrete&& other)
{
- if(_eo_raw) detail::unref(_eo_raw);
_eo_raw = other._eo_raw;
other._eo_raw = nullptr;
}
diff --git a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
index 5a5e8f9535..47b11db1d8 100644
--- a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
@@ -652,7 +652,8 @@ T& convert_to_return(T* value, tag<T*, T&>)
template <typename T>
T convert_to_return(Eo* value, tag<Eo*, T>, typename std::enable_if< eo::is_eolian_object<T>::value>::type* = 0)
{
- return T{value};
+ T v{value};
+ return v;
}
template <typename T>
T convert_to_return(Eo const* value, tag<Eo const*, T>, typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
@@ -799,14 +800,17 @@ struct is_callable : std::false_type {};
template <typename T>
struct is_callable<T, decltype(std::declval<T>() ())> : std::true_type {};
-inline void do_eo_add(Eo*& object, efl::eo::concrete const& parent
- , Efl_Class const* klass)
+template <typename P>
+inline void do_eo_add(Eo*& object, P const& parent
+ , Efl_Class const* klass
+ , typename std::enable_if< eo::is_eolian_object<P>::value>::type* = 0)
{
object = ::_efl_add_internal_start(__FILE__, __LINE__, klass, parent._eo_ptr(), EINA_TRUE, EINA_FALSE);
object = ::_efl_add_end(object, EINA_FALSE, EINA_FALSE);
}
-template <typename F>
-void do_eo_add(Eo*& object, efl::eo::concrete const& parent, Efl_Class const* klass, F f)
+template <typename P, typename F>
+void do_eo_add(Eo*& object, P const& parent, Efl_Class const* klass, F f
+ , typename std::enable_if< eo::is_eolian_object<P>::value>::type* = 0)
{
object = ::_efl_add_internal_start(__FILE__, __LINE__, klass, parent._eo_ptr(), EINA_TRUE, EINA_FALSE);
f();
diff --git a/src/examples/elementary/Makefile.am b/src/examples/elementary/Makefile.am
index a5d7e2af72..9e235764ca 100644
--- a/src/examples/elementary/Makefile.am
+++ b/src/examples/elementary/Makefile.am
@@ -407,6 +407,7 @@ calendar_cxx_example_04 \
calendar_cxx_example_05 \
clock_cxx_example \
icon_cxx_example_01 \
+toolbar_cxx_example_01 \
button_cxx_example_00
# examples_PROGRAMS += \
# table_cxx_example_02 \
@@ -449,6 +450,7 @@ calendar_cxx_example_01_SOURCES = calendar_cxx_example_01.cc
bg_cxx_example_02_SOURCES = bg_cxx_example_02.cc
bg_cxx_example_01_SOURCES = bg_cxx_example_01.cc
button_cxx_example_00_SOURCES = button_cxx_example_00.cc
+toolbar_cxx_example_01_SOURCES = toolbar_cxx_example_01.cc
# table_cxx_example_02_SOURCES = table_cxx_example_02.cc
# table_cxx_example_01_SOURCES = table_cxx_example_01.cc
# spinner_cxx_example_SOURCES = spinner_cxx_example.cc
diff --git a/src/examples/elementary/toolbar_cxx_example_01.cc b/src/examples/elementary/toolbar_cxx_example_01.cc
new file mode 100644
index 0000000000..5d19c4bd2e
--- /dev/null
+++ b/src/examples/elementary/toolbar_cxx_example_01.cc
@@ -0,0 +1,135 @@
+#define ELM_WIDGET_PROTECTED
+#define ELM_WIDGET_CLASS_PROTECTED
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <Elementary.hh>
+#include <Evas.hh>
+
+EAPI int
+elm_main(int argc, char* argv[])
+{
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN);
+
+ using efl::eo::instantiate;
+
+ efl::ui::Win win_1
+ (instantiate,
+ [&]
+ {
+ win_1.text_set("Toolbar");
+ win_1.name_set("toolbar");
+ win_1.type_set(EFL_UI_WIN_BASIC);
+ });
+
+ win_1.autodel_set(true);
+ win_1.eo_cxx::efl::Gfx::size_set(320, 300);
+
+ efl::ui::Box box_1(instantiate, win_1);
+ box_1.hint_weight_set(1.0, 1.0);
+ box_1.visible_set(true);
+
+ elm::Toolbar toolbar_1(instantiate, win_1);
+ toolbar_1.shrink_mode_set(ELM_TOOLBAR_SHRINK_MENU);
+ toolbar_1.hint_weight_set(0, 0);
+ toolbar_1.hint_align_set(-1, 0);
+ toolbar_1.menu_parent_set(win_1);
+ elm::toolbar::Item item_1 = efl::eo::downcast<elm::toolbar::Item>
+ (toolbar_1.item_append("document-print", "Hello", nullptr, nullptr));
+ item_1.disabled_set(true);
+ item_1.priority_set(100);
+ elm::toolbar::Item item_2 = efl::eo::downcast<elm::toolbar::Item>
+ (toolbar_1.item_append("folder-new", "World", nullptr, nullptr));
+ item_2.priority_set(100);
+ elm::toolbar::Item item_3 = efl::eo::downcast<elm::toolbar::Item>
+ (toolbar_1.item_append("object-rotate-right", "H", nullptr, nullptr));
+ item_3.priority_set(150);
+ elm::toolbar::Item item_4 = efl::eo::downcast<elm::toolbar::Item>
+ (toolbar_1.item_append("mail-send", "Comes", nullptr, nullptr));
+ item_4.priority_set(0);
+ elm::toolbar::Item item_5 = efl::eo::downcast<elm::toolbar::Item>
+ (toolbar_1.item_append("clock", "Elementary", nullptr, nullptr));
+ item_5.priority_set(200);
+ elm::toolbar::Item item_6 = efl::eo::downcast<elm::toolbar::Item>
+ (toolbar_1.item_append("refresh", "Menu", nullptr, nullptr));
+ item_6.menu_set(true);
+ item_6.priority_set(9999);
+ elm::Menu menu_1 = efl::eo::downcast<elm::Menu>
+ (item_6.menu_get());
+ elm::menu::Item item_7 = efl::eo::downcast<elm::menu::Item>
+ (menu_1.item_add(nullptr, "edit-cut", "Shrink", nullptr, nullptr));
+ elm::menu::Item item_8 = efl::eo::downcast<elm::menu::Item>
+ (menu_1.item_add(nullptr, "edit-copy", "Mode", nullptr, nullptr));
+ elm::menu::Item item_9 = efl::eo::downcast<elm::menu::Item>
+ (menu_1.item_add(item_8, "edit-paste", "is set to", nullptr, nullptr));
+ elm::menu::Item item_10 = efl::eo::downcast<elm::menu::Item>
+ (menu_1.item_add(nullptr, "edit-delete", "Menu", nullptr, nullptr));
+
+ box_1.pack_end(toolbar_1);
+ elm::Widget table_1(elm_table_add(win_1._eo_ptr()));
+ table_1.hint_weight_set(0.0, 1.0);
+ table_1.hint_align_set(-1, -1);
+ table_1.visible_set(true);
+
+ elm::Widget photo_1(elm_photo_add(win_1._eo_ptr()));
+ elm_photo_size_set(photo_1._eo_ptr(), 40);
+ efl_file_set(photo_1._eo_ptr(), "/opt/e/share/elementary/images/plant_01.jpg", nullptr);
+ photo_1.hint_weight_set(1, 1);
+ photo_1.hint_align_set(0.5, 0.5);
+ photo_1.visible_set(true);
+
+ elm_table_pack(table_1._eo_ptr(), photo_1._eo_ptr(), 0, 0, 1, 1);
+ elm::Widget photo_2(elm_photo_add(win_1._eo_ptr()));
+ elm_photo_size_set(photo_2._eo_ptr(), 80);
+ photo_2.hint_weight_set(1, 1);
+ photo_2.hint_align_set(0.5, 0.5);
+ photo_2.visible_set(true);
+
+ elm_table_pack(table_1._eo_ptr(), photo_2._eo_ptr(), 1, 0, 1, 1);
+ elm::Widget photo_3(elm_photo_add(win_1._eo_ptr()));
+ elm_photo_size_set(photo_3._eo_ptr(), 20);
+ efl_file_set(photo_3._eo_ptr(), "/opt/e/share/elementary/images/sky_01.jpg", nullptr);
+ photo_3.hint_weight_set(1, 1);
+ photo_3.hint_align_set(0.5, 0.5);
+ photo_3.visible_set(true);
+
+ elm_table_pack(table_1._eo_ptr(), photo_3._eo_ptr(), 0, 1, 1, 1);
+ elm::Widget photo_4(elm_photo_add(win_1._eo_ptr()));
+ elm_photo_size_set(photo_4._eo_ptr(), 60);
+ efl_file_set(photo_4._eo_ptr(), "/opt/e/share/elementary/images/sky_02.jpg", nullptr);
+ photo_4.hint_weight_set(1, 1);
+ photo_4.hint_align_set(0.5, 0.5);
+ photo_4.visible_set(true);
+
+ elm_table_pack(table_1._eo_ptr(), photo_4._eo_ptr(), 1, 1, 1, 1);
+ box_1.pack_end(table_1);
+
+ win_1.content_set(box_1);
+
+ auto _item_2_selected_cb = std::bind([&] () {
+ efl_file_set(photo_1._eo_ptr(), "/opt/e/share/elementary/images/rock_01.jpg", nullptr);
+ });
+ efl::eolian::event_add(efl::ui::Selectable::selected_event, item_2, _item_2_selected_cb);
+
+ auto _item_3_selected_cb = std::bind([&] () {
+ efl_file_set(photo_4._eo_ptr(), "/opt/e/share/elementary/images/wood_01.jpg", nullptr);
+ });
+
+ efl::eolian::event_add(efl::ui::Selectable::selected_event, item_3, _item_3_selected_cb);
+ auto _item_4_selected_cb = std::bind([&] () {
+ efl_file_set(photo_4._eo_ptr(), "/opt/e/share/elementary/images/sky_03.jpg", nullptr);
+ });
+
+ efl::eolian::event_add(efl::ui::Selectable::selected_event, item_4, _item_4_selected_cb);
+ auto _item_5_selected_cb = std::bind([&] () {
+ efl_file_set(photo_4._eo_ptr(), nullptr, nullptr);
+ });
+
+ efl::eolian::event_add(efl::ui::Selectable::selected_event, item_5, _item_5_selected_cb);
+
+ elm_run();
+ return 0;
+}
+ELM_MAIN()
diff --git a/src/lib/eolian_cxx/grammar/class_declaration.hpp b/src/lib/eolian_cxx/grammar/class_declaration.hpp
index bed1a5696f..7c9957f07d 100644
--- a/src/lib/eolian_cxx/grammar/class_declaration.hpp
+++ b/src/lib/eolian_cxx/grammar/class_declaration.hpp
@@ -37,7 +37,17 @@ struct class_declaration_generator
(
"namespace efl { namespace eo { template<> struct is_eolian_object< "
"::" << *(lower_case[string] << "::") << string << "> : ::std::true_type {}; } }\n"
- ).generate(sink, std::make_tuple(cpp_namespaces, cls.cxx_name), context)) return false;
+ "namespace efl { namespace eo { template<> struct is_eolian_object< "
+ "::" << *(lower_case[string] << "::") << string << "&> : ::std::true_type {}; } }\n"
+ "namespace efl { namespace eo { template<> struct is_eolian_object< "
+ "::" << *(lower_case[string] << "::") << string << " const> : ::std::true_type {}; } }\n"
+ "namespace efl { namespace eo { template<> struct is_eolian_object< "
+ "::" << *(lower_case[string] << "::") << string << " const&> : ::std::true_type {}; } }\n"
+ ).generate(sink, std::make_tuple
+ (
+ cpp_namespaces, cls.cxx_name, cpp_namespaces, cls.cxx_name
+ , cpp_namespaces, cls.cxx_name, cpp_namespaces, cls.cxx_name
+ ), context)) return false;
return true;
diff --git a/src/lib/eolian_cxx/grammar/class_definition.hpp b/src/lib/eolian_cxx/grammar/class_definition.hpp
index c05ea6d0bf..2e53b6e6a7 100644
--- a/src/lib/eolian_cxx/grammar/class_definition.hpp
+++ b/src/lib/eolian_cxx/grammar/class_definition.hpp
@@ -29,7 +29,7 @@ struct class_definition_generator
if(!as_generator
(
- "struct " << string << " : ::efl::eo::concrete"
+ "struct " << string << " : private ::efl::eo::concrete"
)
.generate(sink, cls.cxx_name, context))
return false;
@@ -46,25 +46,34 @@ struct class_definition_generator
(
scope_tab << "explicit " << string << "( ::Eo* eo)\n"
<< scope_tab << scope_tab << ": ::efl::eo::concrete(eo) {}\n"
- << scope_tab << "explicit " << string << "(std::nullptr_t)\n"
+ << scope_tab << string << "(std::nullptr_t)\n"
<< scope_tab << scope_tab << ": ::efl::eo::concrete(nullptr) {}\n"
+ << scope_tab << "explicit " << string << "() = default;\n"
<< scope_tab << string << "(" << string << " const& other) = default;\n"
<< scope_tab << string << "(" << string << "&& other) = default;\n"
<< scope_tab << string << "& operator=(" << string << " const& other) = default;\n"
<< scope_tab << string << "& operator=(" << string << "&& other) = default;\n"
- << scope_tab << string << "()\n"
+ << scope_tab << "template <typename Derived>\n"
+ << scope_tab << string << "(Derived&& derived\n"
+ << scope_tab << scope_tab << ", typename std::enable_if<\n"
+ << scope_tab << scope_tab << scope_tab << "::efl::eo::is_eolian_object<Derived>::value\n"
+ << scope_tab << scope_tab << scope_tab << " && std::is_base_of< " << string << ", Derived>::value"
+ << scope_tab << scope_tab << scope_tab << ">::type* = 0) : ::efl::eo::concrete(derived._eo_ptr())\n"
+ << scope_tab << "{}\n"
+ << scope_tab << string << "( ::efl::eo::instantiate_t)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "::efl::eolian::do_eo_add( ::efl::eo::concrete::_eo_raw, ::efl::eo::concrete{nullptr}, _eo_class());\n"
<< scope_tab << "}\n"
- << scope_tab << string << "( ::efl::eo::concrete parent)\n"
+ << scope_tab << "template <typename T>\n"
+ << scope_tab << "explicit " << string << "( ::efl::eo::instantiate_t, T&& parent, typename std::enable_if< ::efl::eo::is_eolian_object<T>::value>::type* = 0)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "::efl::eolian::do_eo_add( ::efl::eo::concrete::_eo_raw, parent, _eo_class());\n"
<< scope_tab << "}\n"
- << scope_tab << "template <typename F> " << string << "(F f, typename ::std::enable_if< ::efl::eolian::is_callable<F>::value>::type* = 0)\n"
+ << scope_tab << "template <typename F> " << string << "( ::efl::eo::instantiate_t, F f, typename ::std::enable_if< ::efl::eolian::is_callable<F>::value>::type* = 0)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "::efl::eolian::do_eo_add( ::efl::eo::concrete::_eo_raw, ::efl::eo::concrete{nullptr}, _eo_class(), f);\n"
<< scope_tab << "}\n"
- << scope_tab << "template <typename F> " << string << "( ::efl::eo::concrete parent, F f, typename ::std::enable_if< ::efl::eolian::is_callable<F>::value>::type* = 0)\n"
+ << scope_tab << "template <typename F> " << string << "( ::efl::eo::instantiate_t, ::efl::eo::concrete parent, F f, typename ::std::enable_if< ::efl::eolian::is_callable<F>::value>::type* = 0)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "::efl::eolian::do_eo_add( ::efl::eo::concrete::_eo_raw, parent, _eo_class(), f);\n"
<< scope_tab << "}\n"
@@ -161,8 +170,22 @@ struct class_definition_generator
// /// @endcond
if(!as_generator(scope_tab << "/// @endcond\n").generate(sink, attributes::unused, context)) return false;
- if(!as_generator("};\n").generate(sink, attributes::unused, context)) return false;
+ if(!as_generator( scope_tab << "::efl::eo::concrete const& _get_concrete() const { return *this; }\n"
+ << scope_tab << "::efl::eo::concrete& _get_concrete() { return *this; }\n"
+ ).generate(sink, attributes::unused, context)) return false;
+
+ if(!as_generator( scope_tab << "using ::efl::eo::concrete::_eo_ptr;\n"
+ << scope_tab << "using ::efl::eo::concrete::_release;\n"
+ << scope_tab << "using ::efl::eo::concrete::_reset;\n"
+ << scope_tab << "using ::efl::eo::concrete::operator bool;\n"
+ ).generate(sink, attributes::unused, context)) return false;
+ if(!as_generator( scope_tab << "friend bool operator==(" << string << " const& lhs, " << string << " const& rhs)\n"
+ << scope_tab << "{ return lhs._get_concrete() == rhs._get_concrete(); }\n"
+ << scope_tab << "friend bool operator!=(" << string << " const& lhs, " << string << " const& rhs)\n"
+ << scope_tab << "{ return !(lhs == rhs); }\n"
+ << "};\n").generate(sink, attributes::make_infinite_tuple(cls.cxx_name), context)) return false;
+
// static asserts
if(!as_generator("static_assert(sizeof(" << string << ") == sizeof(Eo*), \"\");\n")
.generate(sink, cls.cxx_name, context)) return false;
diff --git a/src/tests/eina_cxx/eina_cxx_test_iterator.cc b/src/tests/eina_cxx/eina_cxx_test_iterator.cc
index 493fa9a944..6cbd98198a 100644
--- a/src/tests/eina_cxx/eina_cxx_test_iterator.cc
+++ b/src/tests/eina_cxx/eina_cxx_test_iterator.cc
@@ -39,10 +39,10 @@ START_TEST(eina_cxx_eo_iterator_equal)
efl::eina::list<nonamespace::Simple> list;
- nonamespace::Simple const w1;
- nonamespace::Simple const w2;
- nonamespace::Simple const w3;
- nonamespace::Simple const w4;
+ nonamespace::Simple const w1(efl::eo::instantiate);
+ nonamespace::Simple const w2(efl::eo::instantiate);
+ nonamespace::Simple const w3(efl::eo::instantiate);
+ nonamespace::Simple const w4(efl::eo::instantiate);
list.push_back(w1);
list.push_back(w2);
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
index 0e46e84ff6..489a308493 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
@@ -16,7 +16,7 @@ START_TEST(eolian_cxx_test_binding_constructor_only_required)
efl::eo::eo_init init;
nonamespace::Generic g
- (
+ (efl::eo::instantiate,
[&]
{
g.required_ctor_a(1);
@@ -34,7 +34,7 @@ START_TEST(eolian_cxx_test_binding_constructor_all_optionals)
efl::eo::eo_init i;
nonamespace::Generic g
- (
+ (efl::eo::instantiate,
[&]
{
g.required_ctor_a(2);
@@ -55,7 +55,7 @@ START_TEST(eolian_cxx_test_type_generation)
{
efl::eo::eo_init eo_init;
- name1::name2::Type_Generation g;
+ name1::name2::Type_Generation g(efl::eo::instantiate);
}
END_TEST
@@ -63,7 +63,7 @@ START_TEST(eolian_cxx_test_type_generation_in)
{
efl::eo::eo_init i;
- name1::name2::Type_Generation g;
+ name1::name2::Type_Generation g(efl::eo::instantiate);
int v = 42;
g.inrefint(v);
@@ -83,7 +83,7 @@ START_TEST(eolian_cxx_test_type_generation_return)
{
efl::eo::eo_init i;
- name1::name2::Type_Generation g;
+ name1::name2::Type_Generation g(efl::eo::instantiate);
{
int&i = g.returnrefint();
@@ -122,7 +122,7 @@ START_TEST(eolian_cxx_test_type_generation_optional)
using efl::eina::optional;
- name1::name2::Type_Generation g;
+ name1::name2::Type_Generation g(efl::eo::instantiate);
g.optionalinvoidptr(NULL);
g.optionalinvoidptr(&g);
@@ -169,7 +169,7 @@ START_TEST(eolian_cxx_test_type_callback)
bool event1 = false, event2 = false, event3 = false, event4 = false
, event5 = false;
- nonamespace::Generic g;
+ nonamespace::Generic g(efl::eo::instantiate);
efl::eolian::event_add(g.prefix_event1_event, g, [&] (nonamespace::Generic)
{
event1 = true;