From 48b3c127f7c4e7ffc7dbf66013c3ec2812ae9a5f Mon Sep 17 00:00:00 2001 From: Felipe Magno de Almeida Date: Thu, 7 Sep 2017 18:02:43 +0900 Subject: [PATCH] eo-cxx: Require instantiate keyword for constructors calling efl_add to avoid ambiguity --- src/bindings/cxx/eo_cxx/eo_concrete.hh | 3 +- src/bindings/cxx/eo_cxx/eo_cxx_interop.hh | 14 +- src/examples/elementary/Makefile.am | 2 + .../elementary/toolbar_cxx_example_01.cc | 135 ++++++++++++++++++ .../eolian_cxx/grammar/class_declaration.hpp | 12 +- .../eolian_cxx/grammar/class_definition.hpp | 37 ++++- src/tests/eina_cxx/eina_cxx_test_iterator.cc | 8 +- .../eolian_cxx/eolian_cxx_test_binding.cc | 14 +- 8 files changed, 200 insertions(+), 25 deletions(-) create mode 100644 src/examples/elementary/toolbar_cxx_example_01.cc 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 Eo wrappers. /// /// This class creates the concrete version of all C++ Eo 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) template T convert_to_return(Eo* value, tag, typename std::enable_if< eo::is_eolian_object::value>::type* = 0) { - return T{value}; + T v{value}; + return v; } template T convert_to_return(Eo const* value, tag, typename std::enable_if::value>::type* = 0) @@ -799,14 +800,17 @@ struct is_callable : std::false_type {}; template struct is_callable() ())> : std::true_type {}; -inline void do_eo_add(Eo*& object, efl::eo::concrete const& parent - , Efl_Class const* klass) +template +inline void do_eo_add(Eo*& object, P const& parent + , Efl_Class const* klass + , typename std::enable_if< eo::is_eolian_object

::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 -void do_eo_add(Eo*& object, efl::eo::concrete const& parent, Efl_Class const* klass, F f) +template +void do_eo_add(Eo*& object, P const& parent, Efl_Class const* klass, F f + , typename std::enable_if< eo::is_eolian_object

::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 +#include + +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 + (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 + (toolbar_1.item_append("folder-new", "World", nullptr, nullptr)); + item_2.priority_set(100); + elm::toolbar::Item item_3 = efl::eo::downcast + (toolbar_1.item_append("object-rotate-right", "H", nullptr, nullptr)); + item_3.priority_set(150); + elm::toolbar::Item item_4 = efl::eo::downcast + (toolbar_1.item_append("mail-send", "Comes", nullptr, nullptr)); + item_4.priority_set(0); + elm::toolbar::Item item_5 = efl::eo::downcast + (toolbar_1.item_append("clock", "Elementary", nullptr, nullptr)); + item_5.priority_set(200); + elm::toolbar::Item item_6 = efl::eo::downcast + (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 + (item_6.menu_get()); + elm::menu::Item item_7 = efl::eo::downcast + (menu_1.item_add(nullptr, "edit-cut", "Shrink", nullptr, nullptr)); + elm::menu::Item item_8 = efl::eo::downcast + (menu_1.item_add(nullptr, "edit-copy", "Mode", nullptr, nullptr)); + elm::menu::Item item_9 = efl::eo::downcast + (menu_1.item_add(item_8, "edit-paste", "is set to", nullptr, nullptr)); + elm::menu::Item item_10 = efl::eo::downcast + (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 \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::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 \n" + << scope_tab << "explicit " << string << "( ::efl::eo::instantiate_t, T&& parent, typename std::enable_if< ::efl::eo::is_eolian_object::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 " << string << "(F f, typename ::std::enable_if< ::efl::eolian::is_callable::value>::type* = 0)\n" + << scope_tab << "template " << string << "( ::efl::eo::instantiate_t, F f, typename ::std::enable_if< ::efl::eolian::is_callable::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 " << string << "( ::efl::eo::concrete parent, F f, typename ::std::enable_if< ::efl::eolian::is_callable::value>::type* = 0)\n" + << scope_tab << "template " << string << "( ::efl::eo::instantiate_t, ::efl::eo::concrete parent, F f, typename ::std::enable_if< ::efl::eolian::is_callable::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 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;