From 1c88f9ad434e267ea2e88fdcf8874f2513733ac8 Mon Sep 17 00:00:00 2001 From: Ian Vink Date: Thu, 25 May 2023 17:10:42 +0200 Subject: [PATCH] Now cef_binary_113.1.5+ge452d82+chromium-113.0.5672.93_windows64.tar.bz2 working with msys2 mingw64 gcc 12.2.0 --- capi/cef_client.h | 27 +- examples/main_win.c | 12 +- include/base/cef_atomic_flag.h | 97 + include/base/cef_atomic_ref_count.h | 164 +- include/base/cef_atomicops.h | 199 - include/base/cef_auto_reset.h | 90 + include/base/cef_basictypes.h | 13 +- include/base/cef_bind.h | 824 +- include/base/cef_bind_helpers.h | 579 - include/base/cef_build.h | 232 +- include/base/cef_callback.h | 889 +- include/base/cef_callback_forward.h | 24 +- include/base/cef_callback_helpers.h | 222 +- include/base/cef_callback_list.h | 650 +- include/base/cef_cancelable_callback.h | 308 +- include/base/cef_compiler_specific.h | 389 + include/base/cef_lock.h | 52 +- include/base/cef_logging.h | 294 +- include/base/cef_macros.h | 183 +- include/base/cef_move.h | 261 - include/base/cef_platform_thread.h | 47 +- include/base/cef_ptr_util.h | 60 + include/base/cef_ref_counted.h | 544 +- include/base/cef_scoped_ptr.h | 625 -- include/base/cef_scoped_refptr.h | 420 + include/base/cef_string16.h | 214 - include/base/cef_template_util.h | 463 +- include/base/cef_thread_checker.h | 94 +- include/base/cef_thread_collision_warner.h | 276 - include/base/cef_trace_event.h | 421 +- include/base/cef_tuple.h | 1624 +-- include/base/cef_weak_ptr.h | 452 +- include/base/internal/README-TRANSFER.txt | 6 + include/base/internal/cef_atomicops_arm_gcc.h | 325 - .../cef_atomicops_atomicword_compat.h | 124 - include/base/internal/cef_atomicops_mac.h | 223 - include/base/internal/cef_atomicops_x86_gcc.h | 268 - .../base/internal/cef_atomicops_x86_msvc.h | 221 - include/base/internal/cef_bind_internal.h | 4129 ++----- include/base/internal/cef_bind_internal_win.h | 396 - include/base/internal/cef_callback_internal.h | 323 +- include/base/internal/cef_lock_impl.h | 8 +- include/base/internal/cef_net_error_list.h | 1028 ++ .../cef_raw_scoped_refptr_mismatch_checker.h | 144 +- include/base/internal/cef_scoped_policy.h | 53 + include/capi/cef_accessibility_handler_capi.h | 20 +- include/capi/cef_app_capi.h | 157 +- include/capi/cef_audio_handler_capi.h | 121 + include/capi/cef_auth_callback_capi.h | 14 +- include/capi/cef_base_capi.h | 5 + include/capi/cef_browser_capi.h | 770 +- .../capi/cef_browser_process_handler_capi.h | 102 +- include/capi/cef_callback_capi.h | 18 +- include/capi/cef_client_capi.h | 88 +- include/capi/cef_command_handler_capi.h | 120 + include/capi/cef_command_line_capi.h | 97 +- include/capi/cef_context_menu_handler_capi.h | 211 +- include/capi/cef_cookie_capi.h | 153 +- include/capi/cef_crash_util_capi.h | 191 +- .../capi/cef_devtools_message_observer_capi.h | 148 + include/capi/cef_dialog_handler_capi.h | 51 +- include/capi/cef_display_handler_capi.h | 87 +- include/capi/cef_dom_capi.h | 121 +- include/capi/cef_download_handler_capi.h | 64 +- include/capi/cef_download_item_capi.h | 51 +- include/capi/cef_drag_data_capi.h | 85 +- include/capi/cef_drag_handler_capi.h | 30 +- include/capi/cef_extension_capi.h | 56 +- include/capi/cef_extension_handler_capi.h | 128 +- include/capi/cef_file_util_capi.h | 85 +- include/capi/cef_find_handler_capi.h | 23 +- include/capi/cef_focus_handler_capi.h | 27 +- include/capi/cef_frame_capi.h | 141 +- include/capi/cef_frame_handler_capi.h | 202 + include/capi/cef_i18n_util_capi.h | 58 + include/capi/cef_image_capi.h | 109 +- include/capi/cef_jsdialog_handler_capi.h | 71 +- include/capi/cef_keyboard_handler_capi.h | 33 +- include/capi/cef_life_span_handler_capi.h | 254 +- include/capi/cef_load_handler_capi.h | 68 +- include/capi/cef_media_router_capi.h | 342 + include/capi/cef_menu_model_capi.h | 304 +- include/capi/cef_menu_model_delegate_capi.h | 36 +- include/capi/cef_navigation_entry_capi.h | 45 +- include/capi/cef_origin_whitelist_capi.h | 83 +- include/capi/cef_parser_capi.h | 108 +- include/capi/cef_path_util_capi.h | 8 +- include/capi/cef_permission_handler_capi.h | 164 + include/capi/cef_preference_capi.h | 148 + include/capi/cef_print_handler_capi.h | 60 +- include/capi/cef_print_settings_capi.h | 70 +- include/capi/cef_process_message_capi.h | 34 +- include/capi/cef_process_util_capi.h | 20 +- include/capi/cef_registration_capi.h | 63 + include/capi/cef_render_handler_capi.h | 176 +- .../capi/cef_render_process_handler_capi.h | 95 +- include/capi/cef_request_capi.h | 165 +- include/capi/cef_request_context_capi.h | 351 +- .../capi/cef_request_context_handler_capi.h | 83 +- include/capi/cef_request_handler_capi.h | 317 +- include/capi/cef_resource_bundle_capi.h | 62 +- .../capi/cef_resource_bundle_handler_capi.h | 44 +- include/capi/cef_resource_handler_capi.h | 159 +- .../capi/cef_resource_request_handler_capi.h | 255 + include/capi/cef_response_capi.h | 80 +- include/capi/cef_response_filter_capi.h | 72 +- include/capi/cef_scheme_capi.h | 138 +- include/capi/cef_server_capi.h | 328 + ...capi.h => cef_shared_memory_region_capi.h} | 42 +- ...cef_shared_process_message_builder_capi.h} | 77 +- include/capi/cef_ssl_info_capi.h | 22 +- include/capi/cef_ssl_status_capi.h | 20 +- include/capi/cef_stream_capi.h | 106 +- include/capi/cef_string_visitor_capi.h | 10 +- include/capi/cef_task_capi.h | 80 +- include/capi/cef_thread_capi.h | 60 +- include/capi/cef_trace_capi.h | 78 +- include/capi/cef_urlrequest_capi.h | 119 +- include/capi/cef_v8_capi.h | 762 +- include/capi/cef_values_capi.h | 456 +- include/capi/cef_waitable_event_capi.h | 62 +- include/capi/cef_web_plugin_capi.h | 243 - include/capi/cef_x509_certificate_capi.h | 78 +- include/capi/cef_xml_reader_capi.h | 118 +- include/capi/cef_zip_reader_capi.h | 58 +- include/capi/test/cef_test_helpers_capi.h | 16 +- include/capi/test/cef_test_server_capi.h | 197 + include/capi/test/cef_translator_test_capi.h | 298 +- include/capi/views/cef_box_layout_capi.h | 32 +- include/capi/views/cef_browser_view_capi.h | 49 +- .../views/cef_browser_view_delegate_capi.h | 60 +- include/capi/views/cef_button_capi.h | 27 +- include/capi/views/cef_button_delegate_capi.h | 16 +- include/capi/views/cef_display_capi.h | 97 +- include/capi/views/cef_fill_layout_capi.h | 12 +- include/capi/views/cef_label_button_capi.h | 72 +- include/capi/views/cef_layout_capi.h | 18 +- include/capi/views/cef_menu_button_capi.h | 46 +- .../views/cef_menu_button_delegate_capi.h | 24 +- .../capi/views/cef_overlay_controller_capi.h | 217 + include/capi/views/cef_panel_capi.h | 48 +- include/capi/views/cef_panel_delegate_capi.h | 12 +- include/capi/views/cef_scroll_view_capi.h | 30 +- include/capi/views/cef_textfield_capi.h | 120 +- .../capi/views/cef_textfield_delegate_capi.h | 22 +- include/capi/views/cef_view_capi.h | 242 +- include/capi/views/cef_view_delegate_capi.h | 69 +- include/capi/views/cef_window_capi.h | 181 +- include/capi/views/cef_window_delegate_capi.h | 134 +- include/cef_accessibility_handler.h | 66 + .../{cef_version_linux.h => cef_api_hash.h} | 67 +- include/cef_app.h | 190 + include/cef_audio_handler.h | 111 + include/cef_auth_callback.h | 64 + include/cef_base.h | 149 + include/cef_browser.h | 946 ++ include/cef_browser_process_handler.h | 127 + include/cef_callback.h | 75 + include/cef_client.h | 202 + include/cef_command_handler.h | 114 + include/cef_command_ids.h | 403 + include/cef_command_line.h | 210 + include/cef_config.h | 40 + include/cef_context_menu_handler.h | 347 + include/cef_cookie.h | 179 + include/cef_crash_util.h | 145 + include/cef_devtools_message_observer.h | 132 + include/cef_dialog_handler.h | 100 + include/cef_display_handler.h | 163 + include/cef_dom.h | 333 + include/cef_download_handler.h | 134 + include/cef_download_item.h | 154 + include/cef_drag_data.h | 225 + include/cef_drag_handler.h | 82 + include/cef_extension.h | 118 + include/cef_extension_handler.h | 200 + include/cef_file_util.h | 130 + include/cef_find_handler.h | 68 + include/cef_focus_handler.h | 81 + include/cef_frame.h | 255 + include/cef_frame_handler.h | 177 + include/cef_i18n_util.h | 49 + include/cef_image.h | 192 + include/cef_jsdialog_handler.h | 127 + include/cef_keyboard_handler.h | 80 + include/cef_life_span_handler.h | 214 + include/cef_load_handler.h | 117 + include/cef_media_router.h | 317 + include/cef_menu_model.h | 491 + include/cef_menu_model_delegate.h | 108 + include/cef_navigation_entry.h | 121 + include/cef_origin_whitelist.h | 103 + include/cef_pack_resources.h | 1579 +++ include/cef_pack_strings.h | 9857 +++++++++++++++++ include/cef_parser.h | 175 + include/cef_path_util.h | 52 + include/cef_permission_handler.h | 149 + include/cef_preference.h | 134 + include/cef_print_handler.h | 142 + include/cef_print_settings.h | 201 + include/cef_process_message.h | 101 + include/cef_process_util.h | 57 + include/cef_registration.h | 49 + include/cef_render_handler.h | 255 + include/cef_render_process_handler.h | 150 + include/cef_request.h | 354 + include/cef_request_context.h | 319 + include/cef_request_context_handler.h | 96 + include/cef_request_handler.h | 241 + include/cef_resource_bundle.h | 91 + include/cef_resource_bundle_handler.h | 90 + include/cef_resource_handler.h | 206 + include/cef_resource_request_handler.h | 250 + include/cef_response.h | 167 + include/cef_response_filter.h | 99 + include/cef_sandbox_win.h | 91 + include/cef_scheme.h | 122 + include/cef_server.h | 316 + include/cef_shared_memory_region.h | 69 + include/cef_shared_process_message_builder.h | 87 + include/cef_ssl_info.h | 72 + include/cef_ssl_status.h | 83 + include/cef_stream.h | 241 + include/cef_string_visitor.h | 55 + include/cef_task.h | 148 + include/cef_thread.h | 117 + include/cef_trace.h | 111 + include/cef_urlrequest.h | 198 + include/cef_v8.h | 1038 ++ include/cef_values.h | 750 ++ include/{cef_version_win.h => cef_version.h} | 183 +- include/cef_waitable_event.h | 109 + include/cef_x509_certificate.h | 188 + include/cef_xml_reader.h | 266 + include/cef_zip_reader.h | 140 + include/internal/cef_app_win.h | 100 + include/internal/cef_linux.h | 127 - include/internal/cef_logging_internal.h | 12 +- include/internal/cef_mac.h | 134 - include/internal/cef_ptr.h | 304 +- include/internal/cef_string_list.h | 20 +- include/internal/cef_string_map.h | 20 +- include/internal/cef_string_multimap.h | 24 +- include/internal/cef_string_types.h | 77 +- include/internal/cef_string_wrappers.h | 511 +- include/internal/cef_thread_internal.h | 8 +- include/internal/cef_time.h | 103 +- include/internal/cef_time_wrappers.h | 111 + include/internal/cef_types.h | 2737 +++-- include/internal/cef_types_geometry.h | 78 + include/internal/cef_types_linux.h | 111 - include/internal/cef_types_mac.h | 121 - include/internal/cef_types_win.h | 50 +- include/internal/cef_types_wrappers.h | 635 +- include/internal/cef_win.h | 123 +- include/test/cef_test_helpers.h | 70 + include/test/cef_test_server.h | 184 + include/test/cef_translator_test.h | 808 ++ include/views/cef_box_layout.h | 74 + include/views/cef_browser_view.h | 107 + include/views/cef_browser_view_delegate.h | 119 + include/views/cef_button.h | 92 + include/views/cef_button_delegate.h | 65 + include/views/cef_display.h | 172 + include/views/cef_fill_layout.h | 51 + include/views/cef_label_button.h | 149 + include/views/cef_layout.h | 73 + include/views/cef_menu_button.h | 88 + include/views/cef_menu_button_delegate.h | 72 + include/views/cef_overlay_controller.h | 210 + include/views/cef_panel.h | 141 + include/views/cef_panel_delegate.h | 50 + include/views/cef_scroll_view.h | 102 + include/views/cef_textfield.h | 269 + include/views/cef_textfield_delegate.h | 71 + include/views/cef_view.h | 427 + include/views/cef_view_delegate.h | 136 + include/views/cef_window.h | 353 + include/views/cef_window_delegate.h | 211 + include/wrapper/cef_byte_read_handler.h | 80 + include/wrapper/cef_closure_task.h | 117 + include/wrapper/cef_helpers.h | 165 + include/wrapper/cef_message_router.h | 439 + include/wrapper/cef_resource_manager.h | 374 + include/wrapper/cef_scoped_temp_dir.h | 118 + include/wrapper/cef_stream_resource_handler.h | 89 + include/wrapper/cef_xml_object.h | 195 + include/wrapper/cef_zip_archive.h | 143 + 288 files changed, 49294 insertions(+), 19026 deletions(-) create mode 100644 include/base/cef_atomic_flag.h delete mode 100644 include/base/cef_atomicops.h create mode 100644 include/base/cef_auto_reset.h delete mode 100644 include/base/cef_bind_helpers.h create mode 100644 include/base/cef_compiler_specific.h delete mode 100644 include/base/cef_move.h create mode 100644 include/base/cef_ptr_util.h delete mode 100644 include/base/cef_scoped_ptr.h create mode 100644 include/base/cef_scoped_refptr.h delete mode 100644 include/base/cef_string16.h delete mode 100644 include/base/cef_thread_collision_warner.h create mode 100644 include/base/internal/README-TRANSFER.txt delete mode 100644 include/base/internal/cef_atomicops_arm_gcc.h delete mode 100644 include/base/internal/cef_atomicops_atomicword_compat.h delete mode 100644 include/base/internal/cef_atomicops_mac.h delete mode 100644 include/base/internal/cef_atomicops_x86_gcc.h delete mode 100644 include/base/internal/cef_atomicops_x86_msvc.h delete mode 100644 include/base/internal/cef_bind_internal_win.h create mode 100644 include/base/internal/cef_net_error_list.h create mode 100644 include/base/internal/cef_scoped_policy.h create mode 100644 include/capi/cef_audio_handler_capi.h create mode 100644 include/capi/cef_command_handler_capi.h create mode 100644 include/capi/cef_devtools_message_observer_capi.h create mode 100644 include/capi/cef_frame_handler_capi.h create mode 100644 include/capi/cef_i18n_util_capi.h create mode 100644 include/capi/cef_media_router_capi.h create mode 100644 include/capi/cef_permission_handler_capi.h create mode 100644 include/capi/cef_preference_capi.h create mode 100644 include/capi/cef_registration_capi.h create mode 100644 include/capi/cef_resource_request_handler_capi.h create mode 100644 include/capi/cef_server_capi.h rename include/capi/{cef_geolocation_capi.h => cef_shared_memory_region_capi.h} (65%) rename include/capi/{cef_geolocation_handler_capi.h => cef_shared_process_message_builder_capi.h} (50%) delete mode 100644 include/capi/cef_web_plugin_capi.h create mode 100644 include/capi/test/cef_test_server_capi.h create mode 100644 include/capi/views/cef_overlay_controller_capi.h create mode 100644 include/cef_accessibility_handler.h rename include/{cef_version_linux.h => cef_api_hash.h} (57%) create mode 100644 include/cef_app.h create mode 100644 include/cef_audio_handler.h create mode 100644 include/cef_auth_callback.h create mode 100644 include/cef_base.h create mode 100644 include/cef_browser.h create mode 100644 include/cef_browser_process_handler.h create mode 100644 include/cef_callback.h create mode 100644 include/cef_client.h create mode 100644 include/cef_command_handler.h create mode 100644 include/cef_command_ids.h create mode 100644 include/cef_command_line.h create mode 100644 include/cef_config.h create mode 100644 include/cef_context_menu_handler.h create mode 100644 include/cef_cookie.h create mode 100644 include/cef_crash_util.h create mode 100644 include/cef_devtools_message_observer.h create mode 100644 include/cef_dialog_handler.h create mode 100644 include/cef_display_handler.h create mode 100644 include/cef_dom.h create mode 100644 include/cef_download_handler.h create mode 100644 include/cef_download_item.h create mode 100644 include/cef_drag_data.h create mode 100644 include/cef_drag_handler.h create mode 100644 include/cef_extension.h create mode 100644 include/cef_extension_handler.h create mode 100644 include/cef_file_util.h create mode 100644 include/cef_find_handler.h create mode 100644 include/cef_focus_handler.h create mode 100644 include/cef_frame.h create mode 100644 include/cef_frame_handler.h create mode 100644 include/cef_i18n_util.h create mode 100644 include/cef_image.h create mode 100644 include/cef_jsdialog_handler.h create mode 100644 include/cef_keyboard_handler.h create mode 100644 include/cef_life_span_handler.h create mode 100644 include/cef_load_handler.h create mode 100644 include/cef_media_router.h create mode 100644 include/cef_menu_model.h create mode 100644 include/cef_menu_model_delegate.h create mode 100644 include/cef_navigation_entry.h create mode 100644 include/cef_origin_whitelist.h create mode 100644 include/cef_pack_resources.h create mode 100644 include/cef_pack_strings.h create mode 100644 include/cef_parser.h create mode 100644 include/cef_path_util.h create mode 100644 include/cef_permission_handler.h create mode 100644 include/cef_preference.h create mode 100644 include/cef_print_handler.h create mode 100644 include/cef_print_settings.h create mode 100644 include/cef_process_message.h create mode 100644 include/cef_process_util.h create mode 100644 include/cef_registration.h create mode 100644 include/cef_render_handler.h create mode 100644 include/cef_render_process_handler.h create mode 100644 include/cef_request.h create mode 100644 include/cef_request_context.h create mode 100644 include/cef_request_context_handler.h create mode 100644 include/cef_request_handler.h create mode 100644 include/cef_resource_bundle.h create mode 100644 include/cef_resource_bundle_handler.h create mode 100644 include/cef_resource_handler.h create mode 100644 include/cef_resource_request_handler.h create mode 100644 include/cef_response.h create mode 100644 include/cef_response_filter.h create mode 100644 include/cef_sandbox_win.h create mode 100644 include/cef_scheme.h create mode 100644 include/cef_server.h create mode 100644 include/cef_shared_memory_region.h create mode 100644 include/cef_shared_process_message_builder.h create mode 100644 include/cef_ssl_info.h create mode 100644 include/cef_ssl_status.h create mode 100644 include/cef_stream.h create mode 100644 include/cef_string_visitor.h create mode 100644 include/cef_task.h create mode 100644 include/cef_thread.h create mode 100644 include/cef_trace.h create mode 100644 include/cef_urlrequest.h create mode 100644 include/cef_v8.h create mode 100644 include/cef_values.h rename include/{cef_version_win.h => cef_version.h} (56%) create mode 100644 include/cef_waitable_event.h create mode 100644 include/cef_x509_certificate.h create mode 100644 include/cef_xml_reader.h create mode 100644 include/cef_zip_reader.h create mode 100644 include/internal/cef_app_win.h delete mode 100644 include/internal/cef_linux.h delete mode 100644 include/internal/cef_mac.h create mode 100644 include/internal/cef_time_wrappers.h create mode 100644 include/internal/cef_types_geometry.h delete mode 100644 include/internal/cef_types_linux.h delete mode 100644 include/internal/cef_types_mac.h create mode 100644 include/test/cef_test_helpers.h create mode 100644 include/test/cef_test_server.h create mode 100644 include/test/cef_translator_test.h create mode 100644 include/views/cef_box_layout.h create mode 100644 include/views/cef_browser_view.h create mode 100644 include/views/cef_browser_view_delegate.h create mode 100644 include/views/cef_button.h create mode 100644 include/views/cef_button_delegate.h create mode 100644 include/views/cef_display.h create mode 100644 include/views/cef_fill_layout.h create mode 100644 include/views/cef_label_button.h create mode 100644 include/views/cef_layout.h create mode 100644 include/views/cef_menu_button.h create mode 100644 include/views/cef_menu_button_delegate.h create mode 100644 include/views/cef_overlay_controller.h create mode 100644 include/views/cef_panel.h create mode 100644 include/views/cef_panel_delegate.h create mode 100644 include/views/cef_scroll_view.h create mode 100644 include/views/cef_textfield.h create mode 100644 include/views/cef_textfield_delegate.h create mode 100644 include/views/cef_view.h create mode 100644 include/views/cef_view_delegate.h create mode 100644 include/views/cef_window.h create mode 100644 include/views/cef_window_delegate.h create mode 100644 include/wrapper/cef_byte_read_handler.h create mode 100644 include/wrapper/cef_closure_task.h create mode 100644 include/wrapper/cef_helpers.h create mode 100644 include/wrapper/cef_message_router.h create mode 100644 include/wrapper/cef_resource_manager.h create mode 100644 include/wrapper/cef_scoped_temp_dir.h create mode 100644 include/wrapper/cef_stream_resource_handler.h create mode 100644 include/wrapper/cef_xml_object.h create mode 100644 include/wrapper/cef_zip_archive.h diff --git a/capi/cef_client.h b/capi/cef_client.h index 55bfd33..f253bed 100644 --- a/capi/cef_client.h +++ b/capi/cef_client.h @@ -76,15 +76,15 @@ struct _cef_focus_handler_t* CEF_CALLBACK get_focus_handler( return NULL; } -/// -// Return the handler for geolocation permissions requests. If no handler is -// provided geolocation access will be denied by default. -/// -struct _cef_geolocation_handler_t* CEF_CALLBACK get_geolocation_handler( - struct _cef_client_t* self) { - DEBUG_CALLBACK("get_geolocation_handler\n"); - return NULL; -} +// /// +// // Return the handler for geolocation permissions requests. If no handler is +// // provided geolocation access will be denied by default. +// /// +// struct _cef_geolocation_handler_t* CEF_CALLBACK get_geolocation_handler( +// struct _cef_client_t* self) { +// DEBUG_CALLBACK("get_geolocation_handler\n"); +// return NULL; +// } /// // Return the handler for JavaScript dialogs. If no handler is provided the @@ -149,8 +149,11 @@ struct _cef_request_handler_t* CEF_CALLBACK get_request_handler( /// int CEF_CALLBACK on_process_message_received( struct _cef_client_t* self, - struct _cef_browser_t* browser, cef_process_id_t source_process, - struct _cef_process_message_t* message) { + struct _cef_browser_t* browser, + struct _cef_frame_t* frame, + cef_process_id_t source_process, + struct _cef_process_message_t* message +) { DEBUG_CALLBACK("on_process_message_received\n"); return 0; } @@ -166,7 +169,7 @@ void initialize_cef_client(cef_client_t* client) { client->get_download_handler = get_download_handler; client->get_drag_handler = get_drag_handler; client->get_focus_handler = get_focus_handler; - client->get_geolocation_handler = get_geolocation_handler; + // client->get_geolocation_handler = get_geolocation_handler; client->get_jsdialog_handler = get_jsdialog_handler; client->get_keyboard_handler = get_keyboard_handler; client->get_life_span_handler = get_life_span_handler; // Implemented! diff --git a/examples/main_win.c b/examples/main_win.c index 015cd85..c9cbeec 100644 --- a/examples/main_win.c +++ b/examples/main_win.c @@ -11,7 +11,7 @@ #include "capi/cef_client.h" #include "capi/cef_life_span_handler.h" -#include "include/cef_version_win.h" +#include "include/cef_version.h" // Globals cef_life_span_handler_t g_life_span_handler = {}; @@ -79,10 +79,10 @@ int main(int argc, char** argv) { window_info.style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN \ | WS_CLIPSIBLINGS | WS_VISIBLE; window_info.parent_window = NULL; - window_info.x = CW_USEDEFAULT; - window_info.y = CW_USEDEFAULT; - window_info.width = CW_USEDEFAULT; - window_info.height = CW_USEDEFAULT; + // window_info.x = CW_USEDEFAULT; + // window_info.y = CW_USEDEFAULT; + // window_info.width = CW_USEDEFAULT; + // window_info.height = CW_USEDEFAULT; // Window info - window title char window_name[] = "cefcapi example"; @@ -110,7 +110,7 @@ int main(int argc, char** argv) { // synchronous version of this function available. printf("cef_browser_host_create_browser\n"); cef_browser_host_create_browser(&window_info, &client, &cef_url, - &browser_settings, NULL); + &browser_settings, NULL, NULL); // Message loop. There is also cef_do_message_loop_work() // that allow for integrating with existing message loops. diff --git a/include/base/cef_atomic_flag.h b/include/base/cef_atomic_flag.h new file mode 100644 index 0000000..3a2fdbc --- /dev/null +++ b/include/base/cef_atomic_flag.h @@ -0,0 +1,97 @@ +// Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2011 +// Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CEF_INCLUDE_BASE_CEF_ATOMIC_FLAG_H_ +#define CEF_INCLUDE_BASE_CEF_ATOMIC_FLAG_H_ +#pragma once + +#if defined(USING_CHROMIUM_INCLUDES) +// When building CEF include the Chromium header directly. +#include "base/synchronization/atomic_flag.h" + +#else // !USING_CHROMIUM_INCLUDES +// The following is substantially similar to the Chromium implementation. +// If the Chromium implementation diverges the below implementation should be +// updated to match. + +#include + +#include + +#include "include/base/cef_thread_checker.h" + +namespace base { + +/// +/// A flag that can safely be set from one thread and read from other threads. +/// +/// This class IS NOT intended for synchronization between threads. +/// +class AtomicFlag { + public: + AtomicFlag(); + + AtomicFlag(const AtomicFlag&) = delete; + AtomicFlag& operator=(const AtomicFlag&) = delete; + + ~AtomicFlag(); + + /// + /// Set the flag. Must always be called from the same thread. + /// + void Set(); + + /// + /// Returns true iff the flag was set. If this returns true, the current + /// thread is guaranteed to be synchronized with all memory operations on the + /// thread which invoked Set() up until at least the first call to Set() on + /// it. + /// + bool IsSet() const { + // Inline here: this has a measurable performance impact on base::WeakPtr. + return flag_.load(std::memory_order_acquire) != 0; + } + + /// + /// Resets the flag. Be careful when using this: callers might not expect + /// IsSet() to return false after returning true once. + /// + void UnsafeResetForTesting(); + + private: + std::atomic flag_{0}; + base::ThreadChecker set_thread_checker_; +}; + +} // namespace base + +#endif // !USING_CHROMIUM_INCLUDES + +#endif // CEF_INCLUDE_BASE_CEF_ATOMIC_FLAG_H_ diff --git a/include/base/cef_atomic_ref_count.h b/include/base/cef_atomic_ref_count.h index 4d67779..38e8f93 100644 --- a/include/base/cef_atomic_ref_count.h +++ b/include/base/cef_atomic_ref_count.h @@ -43,120 +43,78 @@ // When building CEF include the Chromium header directly. #include "base/atomic_ref_count.h" -// Used when declaring a base::AtomicRefCount value. This is an object type with -// Chromium headers. -#define ATOMIC_DECLARATION (0) - -// Maintaining compatibility with AtompicRefCount* functions that were removed -// from Chromium in http://crrev.com/ee96d561. -namespace base { - -// Increment a reference count by 1. -inline void AtomicRefCountInc(volatile AtomicRefCount* ptr) { - const_cast(ptr)->Increment(); -} - -// Decrement a reference count by 1 and return whether the result is non-zero. -// Insert barriers to ensure that state written before the reference count -// became zero will be visible to a thread that has just made the count zero. -inline bool AtomicRefCountDec(volatile AtomicRefCount* ptr) { - return const_cast(ptr)->Decrement(); -} - -// Return whether the reference count is one. If the reference count is used -// in the conventional way, a refrerence count of 1 implies that the current -// thread owns the reference and no other thread shares it. This call performs -// the test for a reference count of one, and performs the memory barrier -// needed for the owning thread to act on the object, knowing that it has -// exclusive access to the object. -inline bool AtomicRefCountIsOne(volatile AtomicRefCount* ptr) { - return const_cast(ptr)->IsOne(); -} - -// Return whether the reference count is zero. With conventional object -// referencing counting, the object will be destroyed, so the reference count -// should never be zero. Hence this is generally used for a debug check. -inline bool AtomicRefCountIsZero(volatile AtomicRefCount* ptr) { - return const_cast(ptr)->IsZero(); -} - -} // namespace base - #else // !USING_CHROMIUM_INCLUDES // The following is substantially similar to the Chromium implementation. // If the Chromium implementation diverges the below implementation should be // updated to match. -#include "include/base/cef_atomicops.h" - -// Annotations are not currently supported. -#define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ -#define ANNOTATE_HAPPENS_AFTER(obj) /* empty */ - -// Used when declaring a base::AtomicRefCount value. This is an integer/ptr type -// with CEF headers. -#define ATOMIC_DECLARATION = 0 +#include namespace base { -typedef subtle::Atomic32 AtomicRefCount; - -// Increment a reference count by "increment", which must exceed 0. -inline void AtomicRefCountIncN(volatile AtomicRefCount* ptr, - AtomicRefCount increment) { - subtle::NoBarrier_AtomicIncrement(ptr, increment); -} - -// Decrement a reference count by "decrement", which must exceed 0, -// and return whether the result is non-zero. -// Insert barriers to ensure that state written before the reference count -// became zero will be visible to a thread that has just made the count zero. -inline bool AtomicRefCountDecN(volatile AtomicRefCount* ptr, - AtomicRefCount decrement) { - ANNOTATE_HAPPENS_BEFORE(ptr); - bool res = (subtle::Barrier_AtomicIncrement(ptr, -decrement) != 0); - if (!res) { - ANNOTATE_HAPPENS_AFTER(ptr); +class AtomicRefCount { + public: + constexpr AtomicRefCount() : ref_count_(0) {} + explicit constexpr AtomicRefCount(int initial_value) + : ref_count_(initial_value) {} + + /// + /// Increment a reference count. + /// Returns the previous value of the count. + /// + int Increment() { return Increment(1); } + + /// + /// Increment a reference count by "increment", which must exceed 0. + /// Returns the previous value of the count. + /// + int Increment(int increment) { + return ref_count_.fetch_add(increment, std::memory_order_relaxed); + } + + /// + /// Decrement a reference count, and return whether the result is non-zero. + /// Insert barriers to ensure that state written before the reference count + /// became zero will be visible to a thread that has just made the count zero. + /// + bool Decrement() { + // TODO(jbroman): Technically this doesn't need to be an acquire operation + // unless the result is 1 (i.e., the ref count did indeed reach zero). + // However, there are toolchain issues that make that not work as well at + // present (notably TSAN doesn't like it). + return ref_count_.fetch_sub(1, std::memory_order_acq_rel) != 1; } - return res; -} - -// Increment a reference count by 1. -inline void AtomicRefCountInc(volatile AtomicRefCount* ptr) { - base::AtomicRefCountIncN(ptr, 1); -} - -// Decrement a reference count by 1 and return whether the result is non-zero. -// Insert barriers to ensure that state written before the reference count -// became zero will be visible to a thread that has just made the count zero. -inline bool AtomicRefCountDec(volatile AtomicRefCount* ptr) { - return base::AtomicRefCountDecN(ptr, 1); -} - -// Return whether the reference count is one. If the reference count is used -// in the conventional way, a refrerence count of 1 implies that the current -// thread owns the reference and no other thread shares it. This call performs -// the test for a reference count of one, and performs the memory barrier -// needed for the owning thread to act on the object, knowing that it has -// exclusive access to the object. -inline bool AtomicRefCountIsOne(volatile AtomicRefCount* ptr) { - bool res = (subtle::Acquire_Load(ptr) == 1); - if (res) { - ANNOTATE_HAPPENS_AFTER(ptr); + + /// + /// Return whether the reference count is one. If the reference count is used + /// in the conventional way, a refrerence count of 1 implies that the current + /// thread owns the reference and no other thread shares it. This call + /// performs the test for a reference count of one, and performs the memory + /// barrier needed for the owning thread to act on the object, knowing that it + /// has exclusive access to the object. + /// + bool IsOne() const { return ref_count_.load(std::memory_order_acquire) == 1; } + + /// + /// Return whether the reference count is zero. With conventional object + /// referencing counting, the object will be destroyed, so the reference count + /// should never be zero. Hence this is generally used for a debug check. + /// + bool IsZero() const { + return ref_count_.load(std::memory_order_acquire) == 0; } - return res; -} - -// Return whether the reference count is zero. With conventional object -// referencing counting, the object will be destroyed, so the reference count -// should never be zero. Hence this is generally used for a debug check. -inline bool AtomicRefCountIsZero(volatile AtomicRefCount* ptr) { - bool res = (subtle::Acquire_Load(ptr) == 0); - if (res) { - ANNOTATE_HAPPENS_AFTER(ptr); + + /// + /// Returns the current reference count (with no barriers). This is subtle, + /// and should be used only for debugging. + /// + int SubtleRefCountForDebug() const { + return ref_count_.load(std::memory_order_relaxed); } - return res; -} + + private: + std::atomic_int ref_count_; +}; } // namespace base diff --git a/include/base/cef_atomicops.h b/include/base/cef_atomicops.h deleted file mode 100644 index 96aebab..0000000 --- a/include/base/cef_atomicops.h +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2012 -// Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the name Chromium Embedded -// Framework nor the names of its contributors may be used to endorse -// or promote products derived from this software without specific prior -// written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// For atomic operations on reference counts, see cef_atomic_ref_count.h. - -// The routines exported by this module are subtle. If you use them, even if -// you get the code right, it will depend on careful reasoning about atomicity -// and memory ordering; it will be less readable, and harder to maintain. If -// you plan to use these routines, you should have a good reason, such as solid -// evidence that performance would otherwise suffer, or there being no -// alternative. You should assume only properties explicitly guaranteed by the -// specifications in this file. You are almost certainly _not_ writing code -// just for the x86; if you assume x86 semantics, x86 hardware bugs and -// implementations on other archtectures will cause your code to break. If you -// do not know what you are doing, avoid these routines, and use a Mutex. -// -// It is incorrect to make direct assignments to/from an atomic variable. -// You should use one of the Load or Store routines. The NoBarrier -// versions are provided when no barriers are needed: -// NoBarrier_Store() -// NoBarrier_Load() -// Although there are currently no compiler enforcement, you are encouraged -// to use these. -// - -#ifndef CEF_INCLUDE_BASE_CEF_ATOMICOPS_H_ -#define CEF_INCLUDE_BASE_CEF_ATOMICOPS_H_ -#pragma once - -#if defined(BASE_ATOMICOPS_H_) -// Do nothing if the Chromium header has already been included. -// This can happen in cases where Chromium code is used directly by the -// client application. When using Chromium code directly always include -// the Chromium header first to avoid type conflicts. -#elif defined(USING_CHROMIUM_INCLUDES) -// When building CEF include the Chromium header directly. -#include "base/atomicops.h" -#else // !USING_CHROMIUM_INCLUDES -// The following is substantially similar to the Chromium implementation. -// If the Chromium implementation diverges the below implementation should be -// updated to match. - -#include - -#include "include/base/cef_build.h" - -#if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) -// windows.h #defines this (only on x64). This causes problems because the -// public API also uses MemoryBarrier at the public name for this fence. So, on -// X64, undef it, and call its documented -// (http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208.aspx) -// implementation directly. -#undef MemoryBarrier -#endif - -namespace base { -namespace subtle { - -typedef int32_t Atomic32; -#ifdef ARCH_CPU_64_BITS -// We need to be able to go between Atomic64 and AtomicWord implicitly. This -// means Atomic64 and AtomicWord should be the same type on 64-bit. -#if defined(__ILP32__) || defined(OS_NACL) -// NaCl's intptr_t is not actually 64-bits on 64-bit! -// http://code.google.com/p/nativeclient/issues/detail?id=1162 -typedef int64_t Atomic64; -#else -typedef intptr_t Atomic64; -#endif -#endif - -// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or -// Atomic64 routines below, depending on your architecture. -typedef intptr_t AtomicWord; - -// Atomically execute: -// result = *ptr; -// if (*ptr == old_value) -// *ptr = new_value; -// return result; -// -// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". -// Always return the old value of "*ptr" -// -// This routine implies no memory barriers. -Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value); - -// Atomically store new_value into *ptr, returning the previous value held in -// *ptr. This routine implies no memory barriers. -Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value); - -// Atomically increment *ptr by "increment". Returns the new value of -// *ptr with the increment applied. This routine implies no memory barriers. -Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); - -Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); - -// These following lower-level operations are typically useful only to people -// implementing higher-level synchronization operations like spinlocks, -// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or -// a store with appropriate memory-ordering instructions. "Acquire" operations -// ensure that no later memory access can be reordered ahead of the operation. -// "Release" operations ensure that no previous memory access can be reordered -// after the operation. "Barrier" operations have both "Acquire" and "Release" -// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory -// access. -Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value); -Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value); - -void MemoryBarrier(); -void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value); -void Acquire_Store(volatile Atomic32* ptr, Atomic32 value); -void Release_Store(volatile Atomic32* ptr, Atomic32 value); - -Atomic32 NoBarrier_Load(volatile const Atomic32* ptr); -Atomic32 Acquire_Load(volatile const Atomic32* ptr); -Atomic32 Release_Load(volatile const Atomic32* ptr); - -// 64-bit atomic operations (only available on 64-bit processors). -#ifdef ARCH_CPU_64_BITS -Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value); -Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value); -Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); -Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); - -Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value); -Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value); -void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value); -void Acquire_Store(volatile Atomic64* ptr, Atomic64 value); -void Release_Store(volatile Atomic64* ptr, Atomic64 value); -Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); -Atomic64 Acquire_Load(volatile const Atomic64* ptr); -Atomic64 Release_Load(volatile const Atomic64* ptr); -#endif // ARCH_CPU_64_BITS - -} // namespace subtle -} // namespace base - -// Include our platform specific implementation. -#if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY) -#include "include/base/internal/cef_atomicops_x86_msvc.h" -#elif defined(OS_MACOSX) -#include "include/base/internal/cef_atomicops_mac.h" -#elif defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY) -#include "include/base/internal/cef_atomicops_x86_gcc.h" -#elif defined(COMPILER_GCC) && defined(__ARM_ARCH) -#include "include/base/internal/cef_atomicops_arm_gcc.h" -#else -#error "Atomic operations are not supported on your platform" -#endif - -// On some platforms we need additional declarations to make -// AtomicWord compatible with our other Atomic* types. -#if defined(OS_MACOSX) || defined(OS_OPENBSD) -#include "include/base/internal/cef_atomicops_atomicword_compat.h" -#endif - -#endif // !USING_CHROMIUM_INCLUDES - -#endif // CEF_INCLUDE_BASE_CEF_ATOMICOPS_H_ diff --git a/include/base/cef_auto_reset.h b/include/base/cef_auto_reset.h new file mode 100644 index 0000000..be3a05d --- /dev/null +++ b/include/base/cef_auto_reset.h @@ -0,0 +1,90 @@ +// Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2011 +// Google Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// base::AutoReset<> is useful for setting a variable to a new value only within +// a particular scope. An base::AutoReset<> object resets a variable to its +// original value upon destruction, making it an alternative to writing +// "var = false;" or "var = old_val;" at all of a block's exit points. +// +// This should be obvious, but note that an base::AutoReset<> instance should +// have a shorter lifetime than its scoped_variable, to prevent invalid memory +// writes when the base::AutoReset<> object is destroyed. + +#ifndef CEF_INCLUDE_BASE_CEF_AUTO_RESET_H_ +#define CEF_INCLUDE_BASE_CEF_AUTO_RESET_H_ +#pragma once + +#if defined(USING_CHROMIUM_INCLUDES) +// When building CEF include the Chromium header directly. +#include "base/auto_reset.h" +#else // !USING_CHROMIUM_INCLUDES +// The following is substantially similar to the Chromium implementation. +// If the Chromium implementation diverges the below implementation should be +// updated to match. + +#include + +namespace base { + +template +class AutoReset { + public: + template + AutoReset(T* scoped_variable, U&& new_value) + : scoped_variable_(scoped_variable), + original_value_( + std::exchange(*scoped_variable_, std::forward(new_value))) {} + + AutoReset(AutoReset&& other) + : scoped_variable_(std::exchange(other.scoped_variable_, nullptr)), + original_value_(std::move(other.original_value_)) {} + + AutoReset& operator=(AutoReset&& rhs) { + scoped_variable_ = std::exchange(rhs.scoped_variable_, nullptr); + original_value_ = std::move(rhs.original_value_); + return *this; + } + + ~AutoReset() { + if (scoped_variable_) { + *scoped_variable_ = std::move(original_value_); + } + } + + private: + T* scoped_variable_; + T original_value_; +}; + +} // namespace base + +#endif // !USING_CHROMIUM_INCLUDES + +#endif // CEF_INCLUDE_BASE_CEF_AUTO_RESET_H_ diff --git a/include/base/cef_basictypes.h b/include/base/cef_basictypes.h index 0086a1d..4f39e83 100644 --- a/include/base/cef_basictypes.h +++ b/include/base/cef_basictypes.h @@ -42,7 +42,7 @@ // // On Mac OS X, |long long| is used for 64-bit types for compatibility with // format macros even in the LP64 model. -#if defined(__LP64__) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) +#if defined(__LP64__) && !defined(OS_MAC) && !defined(OS_OPENBSD) typedef long int64; typedef unsigned long uint64; #else @@ -64,8 +64,17 @@ typedef int int32; typedef unsigned int uint32; #endif +#ifndef _INT16 +#define _INT16 +typedef short int16; +#endif + +#ifndef _UINT16 +#define _UINT16 +typedef unsigned short uint16; +#endif + // UTF-16 character type. -// This should be kept synchronized with base/strings/string16.h #ifndef char16 #if defined(WCHAR_T_IS_UTF16) typedef wchar_t char16; diff --git a/include/base/cef_bind.h b/include/base/cef_bind.h index 77c9c55..770e373 100644 --- a/include/base/cef_bind.h +++ b/include/base/cef_bind.h @@ -28,546 +28,362 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/// +/// \file +/// base::BindOnce() and base::BindRepeating() are helpers for creating +/// base::OnceCallback and base::RepeatingCallback objects respectively. +/// +/// For a runnable object of n-arity, the base::Bind*() family allows partial +/// application of the first m arguments. The remaining n - m arguments must be +/// passed when invoking the callback with Run(). +/// +///
+///   // The first argument is bound at callback creation; the remaining
+///   // two must be passed when calling Run() on the callback object.
+///   base::OnceCallback cb = base::BindOnce(
+///       [](short x, int y, long z) { return x * y * z; }, 42);
+/// 
+/// +/// When binding to a method, the receiver object must also be specified at +/// callback creation time. When Run() is invoked, the method will be invoked on +/// the specified receiver object. +/// +///
+///   class C : public base::RefCounted { void F(); };
+///   auto instance = base::MakeRefCounted();
+///   auto cb = base::BindOnce(&C::F, instance);
+///   std::move(cb).Run();  // Identical to instance->F()
+/// 
+/// +/// See https://chromium.googlesource.com/chromium/src/+/lkgr/docs/callback.md +/// for the full documentation. +/// + +// Implementation notes +// +// If you're reading the implementation, before proceeding further, you should +// read the top comment of base/internal/cef_bind_internal.h for a definition +// of common terms and concepts. + #ifndef CEF_INCLUDE_BASE_CEF_BIND_H_ #define CEF_INCLUDE_BASE_CEF_BIND_H_ #pragma once -#if defined(BASE_BIND_H_) -// Do nothing if the Chromium header has already been included. -// This can happen in cases where Chromium code is used directly by the -// client application. When using Chromium code directly always include -// the Chromium header first to avoid type conflicts. -#elif defined(USING_CHROMIUM_INCLUDES) +#if defined(USING_CHROMIUM_INCLUDES) // When building CEF include the Chromium header directly. -#include "base/bind.h" +#include "base/functional/bind.h" #else // !USING_CHROMIUM_INCLUDES // The following is substantially similar to the Chromium implementation. // If the Chromium implementation diverges the below implementation should be // updated to match. +#include +#include +#include +#include + +#include "include/base/cef_build.h" +#include "include/base/cef_compiler_specific.h" +#include "include/base/cef_template_util.h" #include "include/base/internal/cef_bind_internal.h" -#include "include/base/internal/cef_callback_internal.h" -// ----------------------------------------------------------------------------- -// Usage documentation -// ----------------------------------------------------------------------------- -// -// See base/cef_callback.h for documentation. -// -// -// ----------------------------------------------------------------------------- -// Implementation notes -// ----------------------------------------------------------------------------- -// -// If you're reading the implementation, before proceeding further, you should -// read the top comment of base/bind_internal.h for a definition of common -// terms and concepts. -// -// RETURN TYPES -// -// Though Bind()'s result is meant to be stored in a Callback<> type, it -// cannot actually return the exact type without requiring a large amount -// of extra template specializations. The problem is that in order to -// discern the correct specialization of Callback<>, Bind would need to -// unwrap the function signature to determine the signature's arity, and -// whether or not it is a method. -// -// Each unique combination of (arity, function_type, num_prebound) where -// function_type is one of {function, method, const_method} would require -// one specialization. We eventually have to do a similar number of -// specializations anyways in the implementation (see the Invoker<>, -// classes). However, it is avoidable in Bind if we return the result -// via an indirection like we do below. -// -// TODO(ajwong): We might be able to avoid this now, but need to test. -// -// It is possible to move most of the COMPILE_ASSERT asserts into BindState<>, -// but it feels a little nicer to have the asserts here so people do not -// need to crack open bind_internal.h. On the other hand, it makes Bind() -// harder to read. +#if defined(OS_APPLE) && !HAS_FEATURE(objc_arc) +#include "include/base/internal/cef_scoped_block_mac.h" +#endif namespace base { -template -base::Callback::RunnableType, - typename cef_internal::FunctorTraits::RunType, - void()>::UnboundRunType> -Bind(Functor functor) { - // Typedefs for how to store and run the functor. - typedef - typename cef_internal::FunctorTraits::RunnableType RunnableType; - typedef typename cef_internal::FunctorTraits::RunType RunType; - - typedef cef_internal::BindState BindState; - - return Callback( - new BindState(cef_internal::MakeRunnable(functor))); +/// +/// Bind as OnceCallback. +/// +template +inline OnceCallback> +BindOnce(Functor&& functor, Args&&... args) { + static_assert(!cef_internal::IsOnceCallback>() || + (std::is_rvalue_reference() && + !std::is_const>()), + "BindOnce requires non-const rvalue for OnceCallback binding." + " I.e.: base::BindOnce(std::move(callback))."); + static_assert( + conjunction>...>::value, + "Use std::move() instead of base::Passed() with base::BindOnce()"); + + return cef_internal::BindImpl(std::forward(functor), + std::forward(args)...); } -template -base::Callback::RunnableType, - typename cef_internal::FunctorTraits::RunType, - void(typename cef_internal::CallbackParamTraits::StorageType)>:: - UnboundRunType> -Bind(Functor functor, const P1& p1) { - // Typedefs for how to store and run the functor. - typedef - typename cef_internal::FunctorTraits::RunnableType RunnableType; - typedef typename cef_internal::FunctorTraits::RunType RunType; - - // Use RunnableType::RunType instead of RunType above because our - // checks should below for bound references need to know what the actual - // functor is going to interpret the argument as. - typedef cef_internal::FunctionTraits - BoundFunctorTraits; - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !(is_non_const_reference::value), - do_not_bind_functions_with_nonconst_ref); - - // For methods, we need to be careful for parameter 1. We do not require - // a scoped_refptr because BindState<> itself takes care of AddRef() for - // methods. We also disallow binding of an array as the method's target - // object. - COMPILE_ASSERT(cef_internal::HasIsMethodTag::value || - !cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::HasIsMethodTag::value || - !is_array::value, - first_bound_argument_to_method_cannot_be_array); - typedef cef_internal::BindState< - RunnableType, RunType, - void(typename cef_internal::CallbackParamTraits::StorageType)> - BindState; - - return Callback( - new BindState(cef_internal::MakeRunnable(functor), p1)); +/// +/// Bind as RepeatingCallback. +/// +template +inline RepeatingCallback> +BindRepeating(Functor&& functor, Args&&... args) { + static_assert( + !cef_internal::IsOnceCallback>(), + "BindRepeating cannot bind OnceCallback. Use BindOnce with std::move()."); + + return cef_internal::BindImpl( + std::forward(functor), std::forward(args)...); } -template -base::Callback::RunnableType, - typename cef_internal::FunctorTraits::RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)>:: - UnboundRunType> -Bind(Functor functor, const P1& p1, const P2& p2) { - // Typedefs for how to store and run the functor. - typedef - typename cef_internal::FunctorTraits::RunnableType RunnableType; - typedef typename cef_internal::FunctorTraits::RunType RunType; - - // Use RunnableType::RunType instead of RunType above because our - // checks should below for bound references need to know what the actual - // functor is going to interpret the argument as. - typedef cef_internal::FunctionTraits - BoundFunctorTraits; - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !(is_non_const_reference::value || - is_non_const_reference::value), - do_not_bind_functions_with_nonconst_ref); - - // For methods, we need to be careful for parameter 1. We do not require - // a scoped_refptr because BindState<> itself takes care of AddRef() for - // methods. We also disallow binding of an array as the method's target - // object. - COMPILE_ASSERT(cef_internal::HasIsMethodTag::value || - !cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::HasIsMethodTag::value || - !is_array::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - typedef cef_internal::BindState< - RunnableType, RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)> - BindState; - - return Callback( - new BindState(cef_internal::MakeRunnable(functor), p1, p2)); +/// +/// Special cases for binding to a base::Callback without extra bound arguments. +/// We CHECK() the validity of callback to guard against null pointers +/// accidentally ending up in posted tasks, causing hard-to-debug crashes. +/// +template +OnceCallback BindOnce(OnceCallback callback) { + CHECK(callback); + return callback; } -template -base::Callback::RunnableType, - typename cef_internal::FunctorTraits::RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)>:: - UnboundRunType> -Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3) { - // Typedefs for how to store and run the functor. - typedef - typename cef_internal::FunctorTraits::RunnableType RunnableType; - typedef typename cef_internal::FunctorTraits::RunType RunType; - - // Use RunnableType::RunType instead of RunType above because our - // checks should below for bound references need to know what the actual - // functor is going to interpret the argument as. - typedef cef_internal::FunctionTraits - BoundFunctorTraits; - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !(is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value), - do_not_bind_functions_with_nonconst_ref); - - // For methods, we need to be careful for parameter 1. We do not require - // a scoped_refptr because BindState<> itself takes care of AddRef() for - // methods. We also disallow binding of an array as the method's target - // object. - COMPILE_ASSERT(cef_internal::HasIsMethodTag::value || - !cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::HasIsMethodTag::value || - !is_array::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p3_is_refcounted_type_and_needs_scoped_refptr); - typedef cef_internal::BindState< - RunnableType, RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)> - BindState; - - return Callback( - new BindState(cef_internal::MakeRunnable(functor), p1, p2, p3)); +template +OnceCallback BindOnce(RepeatingCallback callback) { + CHECK(callback); + return callback; } -template -base::Callback::RunnableType, - typename cef_internal::FunctorTraits::RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)>:: - UnboundRunType> -Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4) { - // Typedefs for how to store and run the functor. - typedef - typename cef_internal::FunctorTraits::RunnableType RunnableType; - typedef typename cef_internal::FunctorTraits::RunType RunType; - - // Use RunnableType::RunType instead of RunType above because our - // checks should below for bound references need to know what the actual - // functor is going to interpret the argument as. - typedef cef_internal::FunctionTraits - BoundFunctorTraits; - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !(is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value), - do_not_bind_functions_with_nonconst_ref); - - // For methods, we need to be careful for parameter 1. We do not require - // a scoped_refptr because BindState<> itself takes care of AddRef() for - // methods. We also disallow binding of an array as the method's target - // object. - COMPILE_ASSERT(cef_internal::HasIsMethodTag::value || - !cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::HasIsMethodTag::value || - !is_array::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p4_is_refcounted_type_and_needs_scoped_refptr); - typedef cef_internal::BindState< - RunnableType, RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)> - BindState; - - return Callback( - new BindState(cef_internal::MakeRunnable(functor), p1, p2, p3, p4)); +template +RepeatingCallback BindRepeating( + RepeatingCallback callback) { + CHECK(callback); + return callback; } -template -base::Callback::RunnableType, - typename cef_internal::FunctorTraits::RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)>:: - UnboundRunType> -Bind(Functor functor, - const P1& p1, - const P2& p2, - const P3& p3, - const P4& p4, - const P5& p5) { - // Typedefs for how to store and run the functor. - typedef - typename cef_internal::FunctorTraits::RunnableType RunnableType; - typedef typename cef_internal::FunctorTraits::RunType RunType; - - // Use RunnableType::RunType instead of RunType above because our - // checks should below for bound references need to know what the actual - // functor is going to interpret the argument as. - typedef cef_internal::FunctionTraits - BoundFunctorTraits; - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !(is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value), - do_not_bind_functions_with_nonconst_ref); - - // For methods, we need to be careful for parameter 1. We do not require - // a scoped_refptr because BindState<> itself takes care of AddRef() for - // methods. We also disallow binding of an array as the method's target - // object. - COMPILE_ASSERT(cef_internal::HasIsMethodTag::value || - !cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::HasIsMethodTag::value || - !is_array::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p4_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p5_is_refcounted_type_and_needs_scoped_refptr); - typedef cef_internal::BindState< - RunnableType, RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)> - BindState; - - return Callback( - new BindState(cef_internal::MakeRunnable(functor), p1, p2, p3, p4, p5)); +/// +/// Unretained() allows binding a non-refcounted class, and to disable +/// refcounting on arguments that are refcounted objects. +/// +/// EXAMPLE OF Unretained(): +/// +///
+///   class Foo {
+///    public:
+///     void func() { cout << "Foo:f" << endl; }
+///   };
+///
+///   // In some function somewhere.
+///   Foo foo;
+///   OnceClosure foo_callback =
+///       BindOnce(&Foo::func, Unretained(&foo));
+///   std::move(foo_callback).Run();  // Prints "Foo:f".
+/// 
+/// +/// Without the Unretained() wrapper on |&foo|, the above call would fail +/// to compile because Foo does not support the AddRef() and Release() methods. +/// +template +inline cef_internal::UnretainedWrapper Unretained(T* o) { + return cef_internal::UnretainedWrapper(o); } -template -base::Callback::RunnableType, - typename cef_internal::FunctorTraits::RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)>:: - UnboundRunType> -Bind(Functor functor, - const P1& p1, - const P2& p2, - const P3& p3, - const P4& p4, - const P5& p5, - const P6& p6) { - // Typedefs for how to store and run the functor. - typedef - typename cef_internal::FunctorTraits::RunnableType RunnableType; - typedef typename cef_internal::FunctorTraits::RunType RunType; - - // Use RunnableType::RunType instead of RunType above because our - // checks should below for bound references need to know what the actual - // functor is going to interpret the argument as. - typedef cef_internal::FunctionTraits - BoundFunctorTraits; - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !(is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value), - do_not_bind_functions_with_nonconst_ref); - - // For methods, we need to be careful for parameter 1. We do not require - // a scoped_refptr because BindState<> itself takes care of AddRef() for - // methods. We also disallow binding of an array as the method's target - // object. - COMPILE_ASSERT(cef_internal::HasIsMethodTag::value || - !cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::HasIsMethodTag::value || - !is_array::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p4_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p5_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p6_is_refcounted_type_and_needs_scoped_refptr); - typedef cef_internal::BindState< - RunnableType, RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)> - BindState; +/// +/// RetainedRef() accepts a ref counted object and retains a reference to it. +/// When the callback is called, the object is passed as a raw pointer. +/// +/// EXAMPLE OF RetainedRef(): +/// +///
+///    void foo(RefCountedBytes* bytes) {}
+///
+///    scoped_refptr bytes = ...;
+///    OnceClosure callback = BindOnce(&foo, base::RetainedRef(bytes));
+///    std::move(callback).Run();
+/// 
+/// +/// Without RetainedRef, the scoped_refptr would try to implicitly convert to +/// a raw pointer and fail compilation: +/// +///
+///    OnceClosure callback = BindOnce(&foo, bytes); // ERROR!
+/// 
+/// +template +inline cef_internal::RetainedRefWrapper RetainedRef(T* o) { + return cef_internal::RetainedRefWrapper(o); +} +template +inline cef_internal::RetainedRefWrapper RetainedRef(scoped_refptr o) { + return cef_internal::RetainedRefWrapper(std::move(o)); +} - return Callback(new BindState( - cef_internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6)); +/// +/// Owned() transfers ownership of an object to the callback resulting from +/// bind; the object will be deleted when the callback is deleted. +/// +/// EXAMPLE OF Owned(): +/// +///
+///   void foo(int* arg) { cout << *arg << endl }
+///
+///   int* pn = new int(1);
+///   RepeatingClosure foo_callback = BindRepeating(&foo, Owned(pn));
+///
+///   foo_callback.Run();  // Prints "1"
+///   foo_callback.Run();  // Prints "1"
+///   *pn = 2;
+///   foo_callback.Run();  // Prints "2"
+///
+///   foo_callback.Reset();  // |pn| is deleted.  Also will happen when
+///                          // |foo_callback| goes out of scope.
+/// 
+/// +/// Without Owned(), someone would have to know to delete |pn| when the last +/// reference to the callback is deleted. +/// +template +inline cef_internal::OwnedWrapper Owned(T* o) { + return cef_internal::OwnedWrapper(o); } -template -base::Callback::RunnableType, - typename cef_internal::FunctorTraits::RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)>:: - UnboundRunType> -Bind(Functor functor, - const P1& p1, - const P2& p2, - const P3& p3, - const P4& p4, - const P5& p5, - const P6& p6, - const P7& p7) { - // Typedefs for how to store and run the functor. - typedef - typename cef_internal::FunctorTraits::RunnableType RunnableType; - typedef typename cef_internal::FunctorTraits::RunType RunType; +template +inline cef_internal::OwnedWrapper Owned( + std::unique_ptr&& ptr) { + return cef_internal::OwnedWrapper(std::move(ptr)); +} - // Use RunnableType::RunType instead of RunType above because our - // checks should below for bound references need to know what the actual - // functor is going to interpret the argument as. - typedef cef_internal::FunctionTraits - BoundFunctorTraits; +/// +/// OwnedRef() stores an object in the callback resulting from +/// bind and passes a reference to the object to the bound function. +/// +/// EXAMPLE OF OwnedRef(): +/// +///
+///   void foo(int& arg) { cout << ++arg << endl }
+///
+///   int counter = 0;
+///   RepeatingClosure foo_callback = BindRepeating(&foo, OwnedRef(counter));
+///
+///   foo_callback.Run();  // Prints "1"
+///   foo_callback.Run();  // Prints "2"
+///   foo_callback.Run();  // Prints "3"
+///
+///   cout << counter;     // Prints "0", OwnedRef creates a copy of counter.
+/// 
+/// +/// Supports OnceCallbacks as well, useful to pass placeholder arguments: +/// +///
+///   void bar(int& ignore, const std::string& s) { cout << s << endl }
+///
+///   OnceClosure bar_callback = BindOnce(&bar, OwnedRef(0), "Hello");
+///
+///   std::move(bar_callback).Run(); // Prints "Hello"
+/// 
+/// +/// Without OwnedRef() it would not be possible to pass a mutable reference to +/// an object owned by the callback. +/// +template +cef_internal::OwnedRefWrapper> OwnedRef(T&& t) { + return cef_internal::OwnedRefWrapper>(std::forward(t)); +} - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - COMPILE_ASSERT( - !(is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value || - is_non_const_reference::value), - do_not_bind_functions_with_nonconst_ref); +/// +/// Passed() is for transferring movable-but-not-copyable types (eg. unique_ptr) +/// through a RepeatingCallback. Logically, this signifies a destructive +/// transfer of the state of the argument into the target function. Invoking +/// RepeatingCallback::Run() twice on a callback that was created with a +/// Passed() argument will CHECK() because the first invocation would have +/// already transferred ownership to the target function. +/// +/// Note that Passed() is not necessary with BindOnce(), as std::move() does the +/// same thing. Avoid Passed() in favor of std::move() with BindOnce(). +/// +/// EXAMPLE OF Passed(): +/// +///
+///   void TakesOwnership(std::unique_ptr arg) { }
+///   std::unique_ptr CreateFoo() { return std::make_unique();
+///   }
+///
+///   auto f = std::make_unique();
+///
+///   // |cb| is given ownership of Foo(). |f| is now NULL.
+///   // You can use std::move(f) in place of &f, but it's more verbose.
+///   RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(&f));
+///
+///   // Run was never called so |cb| still owns Foo() and deletes
+///   // it on Reset().
+///   cb.Reset();
+///
+///   // |cb| is given a new Foo created by CreateFoo().
+///   cb = BindRepeating(&TakesOwnership, Passed(CreateFoo()));
+///
+///   // |arg| in TakesOwnership() is given ownership of Foo(). |cb|
+///   // no longer owns Foo() and, if reset, would not delete Foo().
+///   cb.Run();  // Foo() is now transferred to |arg| and deleted.
+///   cb.Run();  // This CHECK()s since Foo() already been used once.
+/// 
+/// +/// We offer 2 syntaxes for calling Passed(). The first takes an rvalue and is +/// best suited for use with the return value of a function or other temporary +/// rvalues. The second takes a pointer to the scoper and is just syntactic +/// sugar to avoid having to write Passed(std::move(scoper)). +/// +/// Both versions of Passed() prevent T from being an lvalue reference. The +/// first via use of enable_if, and the second takes a T* which will not bind to +/// T&. +/// +template ::value>* = nullptr> +inline cef_internal::PassedWrapper Passed(T&& scoper) { + return cef_internal::PassedWrapper(std::move(scoper)); +} +template +inline cef_internal::PassedWrapper Passed(T* scoper) { + return cef_internal::PassedWrapper(std::move(*scoper)); +} - // For methods, we need to be careful for parameter 1. We do not require - // a scoped_refptr because BindState<> itself takes care of AddRef() for - // methods. We also disallow binding of an array as the method's target - // object. - COMPILE_ASSERT(cef_internal::HasIsMethodTag::value || - !cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p1_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::HasIsMethodTag::value || - !is_array::value, - first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p4_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p5_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p6_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr::value, - p7_is_refcounted_type_and_needs_scoped_refptr); - typedef cef_internal::BindState< - RunnableType, RunType, - void(typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType, - typename cef_internal::CallbackParamTraits::StorageType)> - BindState; +/// +/// IgnoreResult() is used to adapt a function or callback with a return type to +/// one with a void return. This is most useful if you have a function with, +/// say, a pesky ignorable bool return that you want to use with PostTask or +/// something else that expect a callback with a void return. +/// +/// EXAMPLE OF IgnoreResult(): +/// +///
+///   int DoSomething(int arg) { cout << arg << endl; }
+///
+///   // Assign to a callback with a void return type.
+///   OnceCallback cb = BindOnce(IgnoreResult(&DoSomething));
+///   std::move(cb).Run(1);  // Prints "1".
+///
+///   // Prints "2" on |ml|.
+///   ml->PostTask(FROM_HERE, BindOnce(IgnoreResult(&DoSomething), 2);
+/// 
+/// +template +inline cef_internal::IgnoreResultHelper IgnoreResult(T data) { + return cef_internal::IgnoreResultHelper(std::move(data)); +} - return Callback(new BindState( - cef_internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6, p7)); +#if defined(OS_APPLE) && !HAS_FEATURE(objc_arc) + +/// +/// RetainBlock() is used to adapt an Objective-C block when Automated Reference +/// Counting (ARC) is disabled. This is unnecessary when ARC is enabled, as the +/// BindOnce and BindRepeating already support blocks then. +/// +/// EXAMPLE OF RetainBlock(): +/// +///
+///   // Wrap the block and bind it to a callback.
+///   OnceCallback cb =
+///       BindOnce(RetainBlock(^(int n) { NSLog(@"%d", n); }));
+///   std::move(cb).Run(1);  // Logs "1".
+/// 
+/// +template +base::mac::ScopedBlock RetainBlock(R (^block)(Args...)) { + return base::mac::ScopedBlock(block, + base::scoped_policy::RETAIN); } +#endif // defined(OS_APPLE) && !HAS_FEATURE(objc_arc) + } // namespace base #endif // !USING_CHROMIUM_INCLUDES diff --git a/include/base/cef_bind_helpers.h b/include/base/cef_bind_helpers.h deleted file mode 100644 index 2b4798b..0000000 --- a/include/base/cef_bind_helpers.h +++ /dev/null @@ -1,579 +0,0 @@ -// Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2011 -// Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the name Chromium Embedded -// Framework nor the names of its contributors may be used to endorse -// or promote products derived from this software without specific prior -// written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This defines a set of argument wrappers and related factory methods that -// can be used specify the refcounting and reference semantics of arguments -// that are bound by the Bind() function in base/bind.h. -// -// It also defines a set of simple functions and utilities that people want -// when using Callback<> and Bind(). -// -// -// ARGUMENT BINDING WRAPPERS -// -// The wrapper functions are base::Unretained(), base::Owned(), base::Passed(), -// base::ConstRef(), and base::IgnoreResult(). -// -// Unretained() allows Bind() to bind a non-refcounted class, and to disable -// refcounting on arguments that are refcounted objects. -// -// Owned() transfers ownership of an object to the Callback resulting from -// bind; the object will be deleted when the Callback is deleted. -// -// Passed() is for transferring movable-but-not-copyable types (eg. scoped_ptr) -// through a Callback. Logically, this signifies a destructive transfer of -// the state of the argument into the target function. Invoking -// Callback::Run() twice on a Callback that was created with a Passed() -// argument will CHECK() because the first invocation would have already -// transferred ownership to the target function. -// -// ConstRef() allows binding a constant reference to an argument rather -// than a copy. -// -// IgnoreResult() is used to adapt a function or Callback with a return type to -// one with a void return. This is most useful if you have a function with, -// say, a pesky ignorable bool return that you want to use with PostTask or -// something else that expect a Callback with a void return. -// -// EXAMPLE OF Unretained(): -// -// class Foo { -// public: -// void func() { cout << "Foo:f" << endl; } -// }; -// -// // In some function somewhere. -// Foo foo; -// Closure foo_callback = -// Bind(&Foo::func, Unretained(&foo)); -// foo_callback.Run(); // Prints "Foo:f". -// -// Without the Unretained() wrapper on |&foo|, the above call would fail -// to compile because Foo does not support the AddRef() and Release() methods. -// -// -// EXAMPLE OF Owned(): -// -// void foo(int* arg) { cout << *arg << endl } -// -// int* pn = new int(1); -// Closure foo_callback = Bind(&foo, Owned(pn)); -// -// foo_callback.Run(); // Prints "1" -// foo_callback.Run(); // Prints "1" -// *n = 2; -// foo_callback.Run(); // Prints "2" -// -// foo_callback.Reset(); // |pn| is deleted. Also will happen when -// // |foo_callback| goes out of scope. -// -// Without Owned(), someone would have to know to delete |pn| when the last -// reference to the Callback is deleted. -// -// -// EXAMPLE OF ConstRef(): -// -// void foo(int arg) { cout << arg << endl } -// -// int n = 1; -// Closure no_ref = Bind(&foo, n); -// Closure has_ref = Bind(&foo, ConstRef(n)); -// -// no_ref.Run(); // Prints "1" -// has_ref.Run(); // Prints "1" -// -// n = 2; -// no_ref.Run(); // Prints "1" -// has_ref.Run(); // Prints "2" -// -// Note that because ConstRef() takes a reference on |n|, |n| must outlive all -// its bound callbacks. -// -// -// EXAMPLE OF IgnoreResult(): -// -// int DoSomething(int arg) { cout << arg << endl; } -// -// // Assign to a Callback with a void return type. -// Callback cb = Bind(IgnoreResult(&DoSomething)); -// cb->Run(1); // Prints "1". -// -// // Prints "1" on |ml|. -// ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1); -// -// -// EXAMPLE OF Passed(): -// -// void TakesOwnership(scoped_ptr arg) { } -// scoped_ptr CreateFoo() { return scoped_ptr(new Foo()); } -// -// scoped_ptr f(new Foo()); -// -// // |cb| is given ownership of Foo(). |f| is now NULL. -// // You can use f.Pass() in place of &f, but it's more verbose. -// Closure cb = Bind(&TakesOwnership, Passed(&f)); -// -// // Run was never called so |cb| still owns Foo() and deletes -// // it on Reset(). -// cb.Reset(); -// -// // |cb| is given a new Foo created by CreateFoo(). -// cb = Bind(&TakesOwnership, Passed(CreateFoo())); -// -// // |arg| in TakesOwnership() is given ownership of Foo(). |cb| -// // no longer owns Foo() and, if reset, would not delete Foo(). -// cb.Run(); // Foo() is now transferred to |arg| and deleted. -// cb.Run(); // This CHECK()s since Foo() already been used once. -// -// Passed() is particularly useful with PostTask() when you are transferring -// ownership of an argument into a task, but don't necessarily know if the -// task will always be executed. This can happen if the task is cancellable -// or if it is posted to a MessageLoopProxy. -// -// -// SIMPLE FUNCTIONS AND UTILITIES. -// -// DoNothing() - Useful for creating a Closure that does nothing when called. -// DeletePointer() - Useful for creating a Closure that will delete a -// pointer when invoked. Only use this when necessary. -// In most cases MessageLoop::DeleteSoon() is a better -// fit. - -#ifndef CEF_INCLUDE_BASE_CEF_BIND_HELPERS_H_ -#define CEF_INCLUDE_BASE_CEF_BIND_HELPERS_H_ -#pragma once - -#if defined(BASE_BIND_HELPERS_H_) -// Do nothing if the Chromium header has already been included. -// This can happen in cases where Chromium code is used directly by the -// client application. When using Chromium code directly always include -// the Chromium header first to avoid type conflicts. -#elif defined(USING_CHROMIUM_INCLUDES) -// When building CEF include the Chromium header directly. -#include "base/bind_helpers.h" -#else // !USING_CHROMIUM_INCLUDES -// The following is substantially similar to the Chromium implementation. -// If the Chromium implementation diverges the below implementation should be -// updated to match. - -#include "include/base/cef_basictypes.h" -#include "include/base/cef_callback.h" -#include "include/base/cef_template_util.h" -#include "include/base/cef_weak_ptr.h" - -namespace base { -namespace cef_internal { - -// Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T -// for the existence of AddRef() and Release() functions of the correct -// signature. -// -// http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error -// http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence -// http://stackoverflow.com/questions/4358584/sfinae-approach-comparison -// http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions -// -// The last link in particular show the method used below. -// -// For SFINAE to work with inherited methods, we need to pull some extra tricks -// with multiple inheritance. In the more standard formulation, the overloads -// of Check would be: -// -// template -// Yes NotTheCheckWeWant(Helper<&C::TargetFunc>*); -// -// template -// No NotTheCheckWeWant(...); -// -// static const bool value = sizeof(NotTheCheckWeWant(0)) == sizeof(Yes); -// -// The problem here is that template resolution will not match -// C::TargetFunc if TargetFunc does not exist directly in C. That is, if -// TargetFunc in inherited from an ancestor, &C::TargetFunc will not match, -// |value| will be false. This formulation only checks for whether or -// not TargetFunc exist directly in the class being introspected. -// -// To get around this, we play a dirty trick with multiple inheritance. -// First, We create a class BaseMixin that declares each function that we -// want to probe for. Then we create a class Base that inherits from both T -// (the class we wish to probe) and BaseMixin. Note that the function -// signature in BaseMixin does not need to match the signature of the function -// we are probing for; thus it's easiest to just use void(void). -// -// Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an -// ambiguous resolution between BaseMixin and T. This lets us write the -// following: -// -// template -// No GoodCheck(Helper<&C::TargetFunc>*); -// -// template -// Yes GoodCheck(...); -// -// static const bool value = sizeof(GoodCheck(0)) == sizeof(Yes); -// -// Notice here that the variadic version of GoodCheck() returns Yes here -// instead of No like the previous one. Also notice that we calculate |value| -// by specializing GoodCheck() on Base instead of T. -// -// We've reversed the roles of the variadic, and Helper overloads. -// GoodCheck(Helper<&C::TargetFunc>*), when C = Base, fails to be a valid -// substitution if T::TargetFunc exists. Thus GoodCheck(0) will resolve -// to the variadic version if T has TargetFunc. If T::TargetFunc does not -// exist, then &C::TargetFunc is not ambiguous, and the overload resolution -// will prefer GoodCheck(Helper<&C::TargetFunc>*). -// -// This method of SFINAE will correctly probe for inherited names, but it cannot -// typecheck those names. It's still a good enough sanity check though. -// -// Works on gcc-4.2, gcc-4.4, and Visual Studio 2008. -// -// TODO(ajwong): Move to ref_counted.h or template_util.h when we've vetted -// this works well. -// -// TODO(ajwong): Make this check for Release() as well. -// See http://crbug.com/82038. -template -class SupportsAddRefAndRelease { - typedef char Yes[1]; - typedef char No[2]; - - struct BaseMixin { - void AddRef(); - }; - -// MSVC warns when you try to use Base if T has a private destructor, the -// common pattern for refcounted types. It does this even though no attempt to -// instantiate Base is made. We disable the warning for this definition. -#if defined(OS_WIN) -#pragma warning(push) -#pragma warning(disable : 4624) -#endif - struct Base : public T, public BaseMixin {}; -#if defined(OS_WIN) -#pragma warning(pop) -#endif - - template - struct Helper {}; - - template - static No& Check(Helper<&C::AddRef>*); - - template - static Yes& Check(...); - - public: - static const bool value = sizeof(Check(0)) == sizeof(Yes); -}; - -// Helpers to assert that arguments of a recounted type are bound with a -// scoped_refptr. -template -struct UnsafeBindtoRefCountedArgHelper : false_type {}; - -template -struct UnsafeBindtoRefCountedArgHelper - : integral_constant::value> {}; - -template -struct UnsafeBindtoRefCountedArg : false_type {}; - -template -struct UnsafeBindtoRefCountedArg - : UnsafeBindtoRefCountedArgHelper::value, T> {}; - -template -class HasIsMethodTag { - typedef char Yes[1]; - typedef char No[2]; - - template - static Yes& Check(typename U::IsMethod*); - - template - static No& Check(...); - - public: - static const bool value = sizeof(Check(0)) == sizeof(Yes); -}; - -template -class UnretainedWrapper { - public: - explicit UnretainedWrapper(T* o) : ptr_(o) {} - T* get() const { return ptr_; } - - private: - T* ptr_; -}; - -template -class ConstRefWrapper { - public: - explicit ConstRefWrapper(const T& o) : ptr_(&o) {} - const T& get() const { return *ptr_; } - - private: - const T* ptr_; -}; - -template -struct IgnoreResultHelper { - explicit IgnoreResultHelper(T functor) : functor_(functor) {} - - T functor_; -}; - -template -struct IgnoreResultHelper> { - explicit IgnoreResultHelper(const Callback& functor) : functor_(functor) {} - - const Callback& functor_; -}; - -// An alternate implementation is to avoid the destructive copy, and instead -// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to -// a class that is essentially a scoped_ptr<>. -// -// The current implementation has the benefit though of leaving ParamTraits<> -// fully in callback_internal.h as well as avoiding type conversions during -// storage. -template -class OwnedWrapper { - public: - explicit OwnedWrapper(T* o) : ptr_(o) {} - ~OwnedWrapper() { delete ptr_; } - T* get() const { return ptr_; } - OwnedWrapper(const OwnedWrapper& other) { - ptr_ = other.ptr_; - other.ptr_ = NULL; - } - - private: - mutable T* ptr_; -}; - -// PassedWrapper is a copyable adapter for a scoper that ignores const. -// -// It is needed to get around the fact that Bind() takes a const reference to -// all its arguments. Because Bind() takes a const reference to avoid -// unnecessary copies, it is incompatible with movable-but-not-copyable -// types; doing a destructive "move" of the type into Bind() would violate -// the const correctness. -// -// This conundrum cannot be solved without either C++11 rvalue references or -// a O(2^n) blowup of Bind() templates to handle each combination of regular -// types and movable-but-not-copyable types. Thus we introduce a wrapper type -// that is copyable to transmit the correct type information down into -// BindState<>. Ignoring const in this type makes sense because it is only -// created when we are explicitly trying to do a destructive move. -// -// Two notes: -// 1) PassedWrapper supports any type that has a "Pass()" function. -// This is intentional. The whitelisting of which specific types we -// support is maintained by CallbackParamTraits<>. -// 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" -// scoper to a Callback and allow the Callback to execute once. -template -class PassedWrapper { - public: - explicit PassedWrapper(T scoper) : is_valid_(true), scoper_(scoper.Pass()) {} - PassedWrapper(const PassedWrapper& other) - : is_valid_(other.is_valid_), scoper_(other.scoper_.Pass()) {} - T Pass() const { - CHECK(is_valid_); - is_valid_ = false; - return scoper_.Pass(); - } - - private: - mutable bool is_valid_; - mutable T scoper_; -}; - -// Unwrap the stored parameters for the wrappers above. -template -struct UnwrapTraits { - typedef const T& ForwardType; - static ForwardType Unwrap(const T& o) { return o; } -}; - -template -struct UnwrapTraits> { - typedef T* ForwardType; - static ForwardType Unwrap(UnretainedWrapper unretained) { - return unretained.get(); - } -}; - -template -struct UnwrapTraits> { - typedef const T& ForwardType; - static ForwardType Unwrap(ConstRefWrapper const_ref) { - return const_ref.get(); - } -}; - -template -struct UnwrapTraits> { - typedef T* ForwardType; - static ForwardType Unwrap(const scoped_refptr& o) { return o.get(); } -}; - -template -struct UnwrapTraits> { - typedef const WeakPtr& ForwardType; - static ForwardType Unwrap(const WeakPtr& o) { return o; } -}; - -template -struct UnwrapTraits> { - typedef T* ForwardType; - static ForwardType Unwrap(const OwnedWrapper& o) { return o.get(); } -}; - -template -struct UnwrapTraits> { - typedef T ForwardType; - static T Unwrap(PassedWrapper& o) { return o.Pass(); } -}; - -// Utility for handling different refcounting semantics in the Bind() -// function. -template -struct MaybeRefcount; - -template -struct MaybeRefcount { - static void AddRef(const T&) {} - static void Release(const T&) {} -}; - -template -struct MaybeRefcount { - static void AddRef(const T*) {} - static void Release(const T*) {} -}; - -template -struct MaybeRefcount { - static void AddRef(const T&) {} - static void Release(const T&) {} -}; - -template -struct MaybeRefcount { - static void AddRef(T* o) { o->AddRef(); } - static void Release(T* o) { o->Release(); } -}; - -// No need to additionally AddRef() and Release() since we are storing a -// scoped_refptr<> inside the storage object already. -template -struct MaybeRefcount> { - static void AddRef(const scoped_refptr& o) {} - static void Release(const scoped_refptr& o) {} -}; - -template -struct MaybeRefcount { - static void AddRef(const T* o) { o->AddRef(); } - static void Release(const T* o) { o->Release(); } -}; - -// IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a -// method. It is used internally by Bind() to select the correct -// InvokeHelper that will no-op itself in the event the WeakPtr<> for -// the target object is invalidated. -// -// P1 should be the type of the object that will be received of the method. -template -struct IsWeakMethod : public false_type {}; - -template -struct IsWeakMethod> : public true_type {}; - -template -struct IsWeakMethod>> : public true_type {}; - -} // namespace cef_internal - -template -static inline cef_internal::UnretainedWrapper Unretained(T* o) { - return cef_internal::UnretainedWrapper(o); -} - -template -static inline cef_internal::ConstRefWrapper ConstRef(const T& o) { - return cef_internal::ConstRefWrapper(o); -} - -template -static inline cef_internal::OwnedWrapper Owned(T* o) { - return cef_internal::OwnedWrapper(o); -} - -// We offer 2 syntaxes for calling Passed(). The first takes a temporary and -// is best suited for use with the return value of a function. The second -// takes a pointer to the scoper and is just syntactic sugar to avoid having -// to write Passed(scoper.Pass()). -template -static inline cef_internal::PassedWrapper Passed(T scoper) { - return cef_internal::PassedWrapper(scoper.Pass()); -} -template -static inline cef_internal::PassedWrapper Passed(T* scoper) { - return cef_internal::PassedWrapper(scoper->Pass()); -} - -template -static inline cef_internal::IgnoreResultHelper IgnoreResult(T data) { - return cef_internal::IgnoreResultHelper(data); -} - -template -static inline cef_internal::IgnoreResultHelper> IgnoreResult( - const Callback& data) { - return cef_internal::IgnoreResultHelper>(data); -} - -void DoNothing(); - -template -void DeletePointer(T* obj) { - delete obj; -} - -} // namespace base - -#endif // !USING_CHROMIUM_INCLUDES - -#endif // CEF_INCLUDE_BASE_CEF_BIND_HELPERS_H_ diff --git a/include/base/cef_build.h b/include/base/cef_build.h index 1e2065c..48a088c 100644 --- a/include/base/cef_build.h +++ b/include/base/cef_build.h @@ -27,53 +27,132 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/// \file +/// This file adds defines about the platform we're currently building on. +/// +///
+///  Operating System:
+///    OS_AIX / OS_ANDROID / OS_ASMJS / OS_FREEBSD / OS_FUCHSIA / OS_IOS /
+///    OS_LINUX / OS_MAC / OS_NACL (SFI or NONSFI) / OS_NETBSD / OS_OPENBSD /
+///    OS_QNX / OS_SOLARIS / OS_WIN
+///  Operating System family:
+///    OS_APPLE: IOS or MAC
+///    OS_BSD: FREEBSD or NETBSD or OPENBSD
+///    OS_POSIX: AIX or ANDROID or ASMJS or CHROMEOS or FREEBSD or IOS or LINUX
+///              or MAC or NACL or NETBSD or OPENBSD or QNX or SOLARIS
+///
+///  /!\ Note: OS_CHROMEOS is set by the build system, not this file
+///
+///  Compiler:
+///    COMPILER_MSVC / COMPILER_GCC
+///
+///  Processor:
+///    ARCH_CPU_ARM64 / ARCH_CPU_ARMEL / ARCH_CPU_MIPS / ARCH_CPU_MIPS64 /
+///    ARCH_CPU_MIPS64EL / ARCH_CPU_MIPSEL / ARCH_CPU_PPC64 / ARCH_CPU_S390 /
+///    ARCH_CPU_S390X / ARCH_CPU_X86 / ARCH_CPU_X86_64
+///  Processor family:
+///    ARCH_CPU_ARM_FAMILY: ARMEL or ARM64
+///    ARCH_CPU_MIPS_FAMILY: MIPS64EL or MIPSEL or MIPS64 or MIPS
+///    ARCH_CPU_PPC64_FAMILY: PPC64
+///    ARCH_CPU_S390_FAMILY: S390 or S390X
+///    ARCH_CPU_X86_FAMILY: X86 or X86_64
+///  Processor features:
+///    ARCH_CPU_31_BITS / ARCH_CPU_32_BITS / ARCH_CPU_64_BITS
+///    ARCH_CPU_BIG_ENDIAN / ARCH_CPU_LITTLE_ENDIAN
+/// 
+/// + #ifndef CEF_INCLUDE_BASE_CEF_BUILD_H_ #define CEF_INCLUDE_BASE_CEF_BUILD_H_ #pragma once #if defined(USING_CHROMIUM_INCLUDES) // When building CEF include the Chromium header directly. -#include "base/compiler_specific.h" +#include "build/build_config.h" #else // !USING_CHROMIUM_INCLUDES // The following is substantially similar to the Chromium implementation. // If the Chromium implementation diverges the below implementation should be // updated to match. -#if defined(_WIN32) -#ifndef OS_WIN -#define OS_WIN 1 -#endif +// A set of macros to use for platform detection. +#if defined(ANDROID) +#define OS_ANDROID 1 #elif defined(__APPLE__) -#ifndef OS_MACOSX +// Only include TargetConditionals after testing ANDROID as some Android builds +// on the Mac have this header available and it's not needed unless the target +// is really an Apple platform. +#include +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +#define OS_IOS 1 +#else +#define OS_MAC 1 +// For backwards compatibility. #define OS_MACOSX 1 -#endif +#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE #elif defined(__linux__) -#ifndef OS_LINUX +#if !defined(OS_CHROMEOS) +// Do not define OS_LINUX on Chrome OS build. +// The OS_CHROMEOS macro is defined in GN. #define OS_LINUX 1 +#endif // !defined(OS_CHROMEOS) +// Include a system header to pull in features.h for glibc/uclibc macros. +#include +#if defined(__GLIBC__) && !defined(__UCLIBC__) +// We really are using glibc, not uClibc pretending to be glibc. +#define LIBC_GLIBC 1 #endif +#elif defined(_WIN32) +#define OS_WIN 1 +#elif defined(__Fuchsia__) +#define OS_FUCHSIA 1 +#elif defined(__FreeBSD__) +#define OS_FREEBSD 1 +#elif defined(__NetBSD__) +#define OS_NETBSD 1 +#elif defined(__OpenBSD__) +#define OS_OPENBSD 1 +#elif defined(__sun) +#define OS_SOLARIS 1 +#elif defined(__QNXNTO__) +#define OS_QNX 1 +#elif defined(_AIX) +#define OS_AIX 1 +#elif defined(__asmjs__) || defined(__wasm__) +#define OS_ASMJS 1 #else -#error Please add support for your platform in cef_build.h +#error Please add support for your platform in include/base/cef_build.h +#endif +// NOTE: Adding a new port? Please follow +// https://chromium.googlesource.com/chromium/src/+/master/docs/new_port_policy.md + +#if defined(OS_MAC) || defined(OS_IOS) +#define OS_APPLE 1 +#endif + +// For access to standard BSD features, use OS_BSD instead of a +// more specific macro. +#if defined(OS_FREEBSD) || defined(OS_NETBSD) || defined(OS_OPENBSD) +#define OS_BSD 1 #endif // For access to standard POSIXish features, use OS_POSIX instead of a // more specific macro. -#if defined(OS_MACOSX) || defined(OS_LINUX) -#ifndef OS_POSIX +#if defined(OS_AIX) || defined(OS_ANDROID) || defined(OS_ASMJS) || \ + defined(OS_FREEBSD) || defined(OS_IOS) || defined(OS_LINUX) || \ + defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_NACL) || \ + defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_QNX) || \ + defined(OS_SOLARIS) #define OS_POSIX 1 #endif -#endif -// Compiler detection. +// Compiler detection. Note: clang masquerades as GCC on POSIX and as MSVC on +// Windows. #if defined(__GNUC__) -#ifndef COMPILER_GCC #define COMPILER_GCC 1 -#endif #elif defined(_MSC_VER) -#ifndef COMPILER_MSVC #define COMPILER_MSVC 1 -#endif #else -#error Please add support for your compiler in cef_build.h +#error Please add support for your compiler in build/build_config.h #endif // Processor architecture detection. For more info on what's defined, see: @@ -90,31 +169,72 @@ #define ARCH_CPU_X86 1 #define ARCH_CPU_32_BITS 1 #define ARCH_CPU_LITTLE_ENDIAN 1 +#elif defined(__s390x__) +#define ARCH_CPU_S390_FAMILY 1 +#define ARCH_CPU_S390X 1 +#define ARCH_CPU_64_BITS 1 +#define ARCH_CPU_BIG_ENDIAN 1 +#elif defined(__s390__) +#define ARCH_CPU_S390_FAMILY 1 +#define ARCH_CPU_S390 1 +#define ARCH_CPU_31_BITS 1 +#define ARCH_CPU_BIG_ENDIAN 1 +#elif (defined(__PPC64__) || defined(__PPC__)) && defined(__BIG_ENDIAN__) +#define ARCH_CPU_PPC64_FAMILY 1 +#define ARCH_CPU_PPC64 1 +#define ARCH_CPU_64_BITS 1 +#define ARCH_CPU_BIG_ENDIAN 1 +#elif defined(__PPC64__) +#define ARCH_CPU_PPC64_FAMILY 1 +#define ARCH_CPU_PPC64 1 +#define ARCH_CPU_64_BITS 1 +#define ARCH_CPU_LITTLE_ENDIAN 1 #elif defined(__ARMEL__) #define ARCH_CPU_ARM_FAMILY 1 #define ARCH_CPU_ARMEL 1 #define ARCH_CPU_32_BITS 1 #define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__aarch64__) +#elif defined(__aarch64__) || defined(_M_ARM64) #define ARCH_CPU_ARM_FAMILY 1 #define ARCH_CPU_ARM64 1 #define ARCH_CPU_64_BITS 1 #define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__pnacl__) +#elif defined(__pnacl__) || defined(__asmjs__) || defined(__wasm__) #define ARCH_CPU_32_BITS 1 #define ARCH_CPU_LITTLE_ENDIAN 1 #elif defined(__MIPSEL__) +#if defined(__LP64__) +#define ARCH_CPU_MIPS_FAMILY 1 +#define ARCH_CPU_MIPS64EL 1 +#define ARCH_CPU_64_BITS 1 +#define ARCH_CPU_LITTLE_ENDIAN 1 +#else #define ARCH_CPU_MIPS_FAMILY 1 #define ARCH_CPU_MIPSEL 1 #define ARCH_CPU_32_BITS 1 #define ARCH_CPU_LITTLE_ENDIAN 1 +#endif +#elif defined(__MIPSEB__) +#if defined(__LP64__) +#define ARCH_CPU_MIPS_FAMILY 1 +#define ARCH_CPU_MIPS64 1 +#define ARCH_CPU_64_BITS 1 +#define ARCH_CPU_BIG_ENDIAN 1 +#else +#define ARCH_CPU_MIPS_FAMILY 1 +#define ARCH_CPU_MIPS 1 +#define ARCH_CPU_32_BITS 1 +#define ARCH_CPU_BIG_ENDIAN 1 +#endif #else -#error Please add support for your architecture in cef_build.h +#error Please add support for your architecture in include/base/cef_build.h #endif // Type detection for wchar_t. #if defined(OS_WIN) #define WCHAR_T_IS_UTF16 +#elif defined(OS_FUCHSIA) +#define WCHAR_T_IS_UTF32 #elif defined(OS_POSIX) && defined(COMPILER_GCC) && defined(__WCHAR_MAX__) && \ (__WCHAR_MAX__ == 0x7fffffff || __WCHAR_MAX__ == 0xffffffff) #define WCHAR_T_IS_UTF32 @@ -126,72 +246,18 @@ // short wchar works for them. #define WCHAR_T_IS_UTF16 #else -#error Please add support for your compiler in cef_build.h -#endif - -// Annotate a function indicating the caller must examine the return value. -// Use like: -// int foo() WARN_UNUSED_RESULT; -// To explicitly ignore a result, see |ignore_result()| in . -#ifndef WARN_UNUSED_RESULT -#if defined(COMPILER_GCC) -#define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define WARN_UNUSED_RESULT -#endif -#endif // WARN_UNUSED_RESULT - -// Annotate a typedef or function indicating it's ok if it's not used. -// Use like: -// typedef Foo Bar ALLOW_UNUSED_TYPE; -#ifndef ALLOW_UNUSED_TYPE -#if defined(COMPILER_GCC) -#define ALLOW_UNUSED_TYPE __attribute__((unused)) -#else -#define ALLOW_UNUSED_TYPE +#error Please add support for your compiler in include/base/cef_build.h #endif -#endif // ALLOW_UNUSED_TYPE -// Annotate a variable indicating it's ok if the variable is not used. -// (Typically used to silence a compiler warning when the assignment -// is important for some other reason.) -// Use like: -// int x = ...; -// ALLOW_UNUSED_LOCAL(x); -#ifndef ALLOW_UNUSED_LOCAL -#define ALLOW_UNUSED_LOCAL(x) false ? (void)x : (void)0 +#if defined(OS_ANDROID) +// The compiler thinks std::string::const_iterator and "const char*" are +// equivalent types. +#define STD_STRING_ITERATOR_IS_CHAR_POINTER +// The compiler thinks std::u16string::const_iterator and "char16*" are +// equivalent types. +#define BASE_STRING16_ITERATOR_IS_CHAR16_POINTER #endif #endif // !USING_CHROMIUM_INCLUDES -// Annotate a virtual method indicating it must be overriding a virtual method -// in the parent class. -// Use like: -// void foo() OVERRIDE; -// NOTE: This define should only be used in classes exposed to the client since -// C++11 support may not be enabled in client applications. CEF internal classes -// should use the `override` keyword directly. -#ifndef OVERRIDE -#if defined(__clang__) -#define OVERRIDE override -#elif defined(COMPILER_MSVC) && _MSC_VER >= 1600 -// Visual Studio 2010 and later support override. -#define OVERRIDE override -#elif defined(COMPILER_GCC) && __cplusplus >= 201103 && \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700 -// GCC 4.7 supports explicit virtual overrides when C++11 support is enabled. -#define OVERRIDE override -#else -#define OVERRIDE -#endif -#endif // OVERRIDE - -// Check for C++11 template alias support which was added in VS2013 and GCC4.7. -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf -#if __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1800) || \ - (defined(__GNUC__) && \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ >= 40700)) -#define HAS_CPP11_TEMPLATE_ALIAS_SUPPORT -#endif - #endif // CEF_INCLUDE_BASE_CEF_BUILD_H_ diff --git a/include/base/cef_callback.h b/include/base/cef_callback.h index 16e238a..bcfe499 100644 --- a/include/base/cef_callback.h +++ b/include/base/cef_callback.h @@ -28,772 +28,221 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/// \file +/// A callback is similar in concept to a function pointer: it wraps a runnable +/// object such as a function, method, lambda, or even another callback, +/// allowing the runnable object to be invoked later via the callback object. +/// +/// Unlike function pointers, callbacks are created with base::BindOnce() or +/// base::BindRepeating() and support partial function application. +/// +/// A base::OnceCallback may be Run() at most once; a base::RepeatingCallback +/// may be Run() any number of times. |is_null()| is guaranteed to return true +/// for a moved-from callback. +/// +///
+///   // The lambda takes two arguments, but the first argument |x| is bound at
+///   // callback creation.
+///   base::OnceCallback cb = base::BindOnce([] (int x, int y) {
+///     return x + y;
+///   }, 1);
+///   // Run() only needs the remaining unbound argument |y|.
+///   printf("1 + 2 = %d\n", std::move(cb).Run(2));  // Prints 3
+///   printf("cb is null? %s\n",
+///          cb.is_null() ? "true" : "false");  // Prints true
+///   std::move(cb).Run(2);  // Crashes since |cb| has already run.
+/// 
+/// +/// Callbacks also support cancellation. A common use is binding the receiver +/// object as a WeakPtr. If that weak pointer is invalidated, calling Run() +/// will be a no-op. Note that |IsCancelled()| and |is_null()| are distinct: +/// simply cancelling a callback will not also make it null. +/// +/// See https://chromium.googlesource.com/chromium/src/+/lkgr/docs/callback.md +/// for the full documentation. + #ifndef CEF_INCLUDE_BASE_CEF_CALLBACK_H_ #define CEF_INCLUDE_BASE_CEF_CALLBACK_H_ #pragma once -#if defined(BASE_CALLBACK_H_) -// Do nothing if the Chromium header has already been included. -// This can happen in cases where Chromium code is used directly by the -// client application. When using Chromium code directly always include -// the Chromium header first to avoid type conflicts. -#elif defined(USING_CHROMIUM_INCLUDES) +#if defined(USING_CHROMIUM_INCLUDES) // When building CEF include the Chromium header directly. -#include "base/callback.h" +#include "base/functional/callback.h" #else // !USING_CHROMIUM_INCLUDES // The following is substantially similar to the Chromium implementation. // If the Chromium implementation diverges the below implementation should be // updated to match. +#include + +#include "include/base/cef_bind.h" #include "include/base/cef_callback_forward.h" -#include "include/base/cef_template_util.h" +#include "include/base/cef_logging.h" #include "include/base/internal/cef_callback_internal.h" -// NOTE: Header files that do not require the full definition of Callback or -// Closure should #include "base/cef_callback_forward.h" instead of this file. - -// ----------------------------------------------------------------------------- -// Introduction -// ----------------------------------------------------------------------------- -// -// The templated Callback class is a generalized function object. Together -// with the Bind() function in bind.h, they provide a type-safe method for -// performing partial application of functions. -// -// Partial application (or "currying") is the process of binding a subset of -// a function's arguments to produce another function that takes fewer -// arguments. This can be used to pass around a unit of delayed execution, -// much like lexical closures are used in other languages. For example, it -// is used in Chromium code to schedule tasks on different MessageLoops. -// -// A callback with no unbound input parameters (base::Callback) -// is called a base::Closure. Note that this is NOT the same as what other -// languages refer to as a closure -- it does not retain a reference to its -// enclosing environment. -// -// MEMORY MANAGEMENT AND PASSING -// -// The Callback objects themselves should be passed by const-reference, and -// stored by copy. They internally store their state via a refcounted class -// and thus do not need to be deleted. -// -// The reason to pass via a const-reference is to avoid unnecessary -// AddRef/Release pairs to the internal state. -// -// -// ----------------------------------------------------------------------------- -// Quick reference for basic stuff -// ----------------------------------------------------------------------------- -// -// BINDING A BARE FUNCTION -// -// int Return5() { return 5; } -// base::Callback func_cb = base::Bind(&Return5); -// LOG(INFO) << func_cb.Run(); // Prints 5. -// -// BINDING A CLASS METHOD -// -// The first argument to bind is the member function to call, the second is -// the object on which to call it. -// -// class Ref : public base::RefCountedThreadSafe { -// public: -// int Foo() { return 3; } -// void PrintBye() { LOG(INFO) << "bye."; } -// }; -// scoped_refptr ref = new Ref(); -// base::Callback ref_cb = base::Bind(&Ref::Foo, ref); -// LOG(INFO) << ref_cb.Run(); // Prints out 3. -// -// By default the object must support RefCounted or you will get a compiler -// error. If you're passing between threads, be sure it's -// RefCountedThreadSafe! See "Advanced binding of member functions" below if -// you don't want to use reference counting. -// -// RUNNING A CALLBACK -// -// Callbacks can be run with their "Run" method, which has the same -// signature as the template argument to the callback. -// -// void DoSomething(const base::Callback& callback) { -// callback.Run(5, "hello"); -// } -// -// Callbacks can be run more than once (they don't get deleted or marked when -// run). However, this precludes using base::Passed (see below). -// -// void DoSomething(const base::Callback& callback) { -// double myresult = callback.Run(3.14159); -// myresult += callback.Run(2.71828); -// } -// -// PASSING UNBOUND INPUT PARAMETERS -// -// Unbound parameters are specified at the time a callback is Run(). They are -// specified in the Callback template type: -// -// void MyFunc(int i, const std::string& str) {} -// base::Callback cb = base::Bind(&MyFunc); -// cb.Run(23, "hello, world"); -// -// PASSING BOUND INPUT PARAMETERS -// -// Bound parameters are specified when you create thee callback as arguments -// to Bind(). They will be passed to the function and the Run()ner of the -// callback doesn't see those values or even know that the function it's -// calling. -// -// void MyFunc(int i, const std::string& str) {} -// base::Callback cb = base::Bind(&MyFunc, 23, "hello world"); -// cb.Run(); -// -// A callback with no unbound input parameters (base::Callback) -// is called a base::Closure. So we could have also written: -// -// base::Closure cb = base::Bind(&MyFunc, 23, "hello world"); -// -// When calling member functions, bound parameters just go after the object -// pointer. -// -// base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world"); -// -// PARTIAL BINDING OF PARAMETERS -// -// You can specify some parameters when you create the callback, and specify -// the rest when you execute the callback. -// -// void MyFunc(int i, const std::string& str) {} -// base::Callback cb = base::Bind(&MyFunc, 23); -// cb.Run("hello world"); -// -// When calling a function bound parameters are first, followed by unbound -// parameters. -// -// -// ----------------------------------------------------------------------------- -// Quick reference for advanced binding -// ----------------------------------------------------------------------------- -// -// BINDING A CLASS METHOD WITH WEAK POINTERS -// -// base::Bind(&MyClass::Foo, GetWeakPtr()); -// -// The callback will not be run if the object has already been destroyed. -// DANGER: weak pointers are not threadsafe, so don't use this -// when passing between threads! -// -// BINDING A CLASS METHOD WITH MANUAL LIFETIME MANAGEMENT -// -// base::Bind(&MyClass::Foo, base::Unretained(this)); -// -// This disables all lifetime management on the object. You're responsible -// for making sure the object is alive at the time of the call. You break it, -// you own it! -// -// BINDING A CLASS METHOD AND HAVING THE CALLBACK OWN THE CLASS -// -// MyClass* myclass = new MyClass; -// base::Bind(&MyClass::Foo, base::Owned(myclass)); -// -// The object will be deleted when the callback is destroyed, even if it's -// not run (like if you post a task during shutdown). Potentially useful for -// "fire and forget" cases. -// -// IGNORING RETURN VALUES -// -// Sometimes you want to call a function that returns a value in a callback -// that doesn't expect a return value. -// -// int DoSomething(int arg) { cout << arg << endl; } -// base::Callback) cb = -// base::Bind(base::IgnoreResult(&DoSomething)); -// -// -// ----------------------------------------------------------------------------- -// Quick reference for binding parameters to Bind() -// ----------------------------------------------------------------------------- -// -// Bound parameters are specified as arguments to Bind() and are passed to the -// function. A callback with no parameters or no unbound parameters is called a -// Closure (base::Callback and base::Closure are the same thing). -// -// PASSING PARAMETERS OWNED BY THE CALLBACK -// -// void Foo(int* arg) { cout << *arg << endl; } -// int* pn = new int(1); -// base::Closure foo_callback = base::Bind(&foo, base::Owned(pn)); -// -// The parameter will be deleted when the callback is destroyed, even if it's -// not run (like if you post a task during shutdown). -// -// PASSING PARAMETERS AS A scoped_ptr -// -// void TakesOwnership(scoped_ptr arg) {} -// scoped_ptr f(new Foo); -// // f becomes null during the following call. -// base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f)); -// -// Ownership of the parameter will be with the callback until the it is run, -// when ownership is passed to the callback function. This means the callback -// can only be run once. If the callback is never run, it will delete the -// object when it's destroyed. -// -// PASSING PARAMETERS AS A scoped_refptr -// -// void TakesOneRef(scoped_refptr arg) {} -// scoped_refptr f(new Foo) -// base::Closure cb = base::Bind(&TakesOneRef, f); -// -// This should "just work." The closure will take a reference as long as it -// is alive, and another reference will be taken for the called function. -// -// PASSING PARAMETERS BY REFERENCE -// -// Const references are *copied* unless ConstRef is used. Example: -// -// void foo(const int& arg) { printf("%d %p\n", arg, &arg); } -// int n = 1; -// base::Closure has_copy = base::Bind(&foo, n); -// base::Closure has_ref = base::Bind(&foo, base::ConstRef(n)); -// n = 2; -// foo(n); // Prints "2 0xaaaaaaaaaaaa" -// has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb" -// has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa" -// -// Normally parameters are copied in the closure. DANGER: ConstRef stores a -// const reference instead, referencing the original parameter. This means -// that you must ensure the object outlives the callback! -// -// -// ----------------------------------------------------------------------------- -// Implementation notes -// ----------------------------------------------------------------------------- -// -// WHERE IS THIS DESIGN FROM: -// -// The design Callback and Bind is heavily influenced by C++'s -// tr1::function/tr1::bind, and by the "Google Callback" system used inside -// Google. -// -// -// HOW THE IMPLEMENTATION WORKS: -// -// There are three main components to the system: -// 1) The Callback classes. -// 2) The Bind() functions. -// 3) The arguments wrappers (e.g., Unretained() and ConstRef()). -// -// The Callback classes represent a generic function pointer. Internally, -// it stores a refcounted piece of state that represents the target function -// and all its bound parameters. Each Callback specialization has a templated -// constructor that takes an BindState<>*. In the context of the constructor, -// the static type of this BindState<> pointer uniquely identifies the -// function it is representing, all its bound parameters, and a Run() method -// that is capable of invoking the target. -// -// Callback's constructor takes the BindState<>* that has the full static type -// and erases the target function type as well as the types of the bound -// parameters. It does this by storing a pointer to the specific Run() -// function, and upcasting the state of BindState<>* to a -// BindStateBase*. This is safe as long as this BindStateBase pointer -// is only used with the stored Run() pointer. -// -// To BindState<> objects are created inside the Bind() functions. -// These functions, along with a set of internal templates, are responsible for -// -// - Unwrapping the function signature into return type, and parameters -// - Determining the number of parameters that are bound -// - Creating the BindState storing the bound parameters -// - Performing compile-time asserts to avoid error-prone behavior -// - Returning an Callback<> with an arity matching the number of unbound -// parameters and that knows the correct refcounting semantics for the -// target object if we are binding a method. -// -// The Bind functions do the above using type-inference, and template -// specializations. -// -// By default Bind() will store copies of all bound parameters, and attempt -// to refcount a target object if the function being bound is a class method. -// These copies are created even if the function takes parameters as const -// references. (Binding to non-const references is forbidden, see bind.h.) -// -// To change this behavior, we introduce a set of argument wrappers -// (e.g., Unretained(), and ConstRef()). These are simple container templates -// that are passed by value, and wrap a pointer to argument. See the -// file-level comment in base/bind_helpers.h for more info. -// -// These types are passed to the Unwrap() functions, and the MaybeRefcount() -// functions respectively to modify the behavior of Bind(). The Unwrap() -// and MaybeRefcount() functions change behavior by doing partial -// specialization based on whether or not a parameter is a wrapper type. -// -// ConstRef() is similar to tr1::cref. Unretained() is specific to Chromium. -// -// -// WHY NOT TR1 FUNCTION/BIND? -// -// Direct use of tr1::function and tr1::bind was considered, but ultimately -// rejected because of the number of copy constructors invocations involved -// in the binding of arguments during construction, and the forwarding of -// arguments during invocation. These copies will no longer be an issue in -// C++0x because C++0x will support rvalue reference allowing for the compiler -// to avoid these copies. However, waiting for C++0x is not an option. -// -// Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the -// tr1::bind call itself will invoke a non-trivial copy constructor three times -// for each bound parameter. Also, each when passing a tr1::function, each -// bound argument will be copied again. -// -// In addition to the copies taken at binding and invocation, copying a -// tr1::function causes a copy to be made of all the bound parameters and -// state. -// -// Furthermore, in Chromium, it is desirable for the Callback to take a -// reference on a target object when representing a class method call. This -// is not supported by tr1. -// -// Lastly, tr1::function and tr1::bind has a more general and flexible API. -// This includes things like argument reordering by use of -// tr1::bind::placeholder, support for non-const reference parameters, and some -// limited amount of subtyping of the tr1::function object (e.g., -// tr1::function is convertible to tr1::function). -// -// These are not features that are required in Chromium. Some of them, such as -// allowing for reference parameters, and subtyping of functions, may actually -// become a source of errors. Removing support for these features actually -// allows for a simpler implementation, and a terser Currying API. -// -// -// WHY NOT GOOGLE CALLBACKS? -// -// The Google callback system also does not support refcounting. Furthermore, -// its implementation has a number of strange edge cases with respect to type -// conversion of its arguments. In particular, the argument's constness must -// at times match exactly the function signature, or the type-inference might -// break. Given the above, writing a custom solution was easier. -// -// -// MISSING FUNCTIONALITY -// - Invoking the return of Bind. Bind(&foo).Run() does not work; -// - Binding arrays to functions that take a non-const pointer. -// Example: -// void Foo(const char* ptr); -// void Bar(char* ptr); -// Bind(&Foo, "test"); -// Bind(&Bar, "test"); // This fails because ptr is not const. - namespace base { -// First, we forward declare the Callback class template. This informs the -// compiler that the template only has 1 type parameter which is the function -// signature that the Callback is representing. -// -// After this, create template specializations for 0-7 parameters. Note that -// even though the template typelist grows, the specialization still -// only has one type: the function signature. -// -// If you are thinking of forward declaring Callback in your own header file, -// please include "base/callback_forward.h" instead. -template -class Callback; - -namespace cef_internal { -template -struct BindState; -} // namespace cef_internal - -template -class Callback : public cef_internal::CallbackBase { +template +class OnceCallback : public cef_internal::CallbackBase { public: - typedef R(RunType)(); - - Callback() : CallbackBase(NULL) {} + using ResultType = R; + using RunType = R(Args...); + using PolymorphicInvoke = R (*)(cef_internal::BindStateBase*, + cef_internal::PassingType...); - // Note that this constructor CANNOT be explicit, and that Bind() CANNOT - // return the exact Callback<> type. See base/bind.h for details. - template - Callback( - cef_internal::BindState* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &cef_internal::BindState::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast(invoke_func); - } + constexpr OnceCallback() = default; + OnceCallback(std::nullptr_t) = delete; - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); - } + explicit OnceCallback(cef_internal::BindStateBase* bind_state) + : cef_internal::CallbackBase(bind_state) {} - R Run() const { - PolymorphicInvoke f = - reinterpret_cast(polymorphic_invoke_); + OnceCallback(const OnceCallback&) = delete; + OnceCallback& operator=(const OnceCallback&) = delete; - return f(bind_state_.get()); - } - - private: - typedef R (*PolymorphicInvoke)(cef_internal::BindStateBase*); -}; - -template -class Callback : public cef_internal::CallbackBase { - public: - typedef R(RunType)(A1); + OnceCallback(OnceCallback&&) noexcept = default; + OnceCallback& operator=(OnceCallback&&) noexcept = default; - Callback() : CallbackBase(NULL) {} + OnceCallback(RepeatingCallback other) + : cef_internal::CallbackBase(std::move(other)) {} - // Note that this constructor CANNOT be explicit, and that Bind() CANNOT - // return the exact Callback<> type. See base/bind.h for details. - template - Callback( - cef_internal::BindState* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &cef_internal::BindState::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast(invoke_func); + OnceCallback& operator=(RepeatingCallback other) { + static_cast(*this) = std::move(other); + return *this; } - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); + R Run(Args... args) const& { + static_assert(!sizeof(*this), + "OnceCallback::Run() may only be invoked on a non-const " + "rvalue, i.e. std::move(callback).Run()."); + NOTREACHED(); } - R Run(typename cef_internal::CallbackParamTraits::ForwardType a1) const { + R Run(Args... args) && { + // Move the callback instance into a local variable before the invocation, + // that ensures the internal state is cleared after the invocation. + // It's not safe to touch |this| after the invocation, since running the + // bound function may destroy |this|. + OnceCallback cb = std::move(*this); PolymorphicInvoke f = - reinterpret_cast(polymorphic_invoke_); - - return f(bind_state_.get(), cef_internal::CallbackForward(a1)); + reinterpret_cast(cb.polymorphic_invoke()); + return f(cb.bind_state_.get(), std::forward(args)...); + } + + // Then() returns a new OnceCallback that receives the same arguments as + // |this|, and with the return type of |then|. The returned callback will: + // 1) Run the functor currently bound to |this| callback. + // 2) Run the |then| callback with the result from step 1 as its single + // argument. + // 3) Return the value from running the |then| callback. + // + // Since this method generates a callback that is a replacement for `this`, + // `this` will be consumed and reset to a null callback to ensure the + // originally-bound functor can be run at most once. + template + OnceCallback Then(OnceCallback then) && { + CHECK(then); + return BindOnce( + cef_internal::ThenHelper< + OnceCallback, OnceCallback>::CreateTrampoline(), + std::move(*this), std::move(then)); + } + + // This overload is required; even though RepeatingCallback is implicitly + // convertible to OnceCallback, that conversion will not used when matching + // for template argument deduction. + template + OnceCallback Then( + RepeatingCallback then) && { + CHECK(then); + return BindOnce( + cef_internal::ThenHelper< + OnceCallback, + RepeatingCallback>::CreateTrampoline(), + std::move(*this), std::move(then)); } - - private: - typedef R (*PolymorphicInvoke)( - cef_internal::BindStateBase*, - typename cef_internal::CallbackParamTraits::ForwardType); }; -template -class Callback : public cef_internal::CallbackBase { +template +class RepeatingCallback + : public cef_internal::CallbackBaseCopyable { public: - typedef R(RunType)(A1, A2); - - Callback() : CallbackBase(NULL) {} - - // Note that this constructor CANNOT be explicit, and that Bind() CANNOT - // return the exact Callback<> type. See base/bind.h for details. - template - Callback( - cef_internal::BindState* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &cef_internal::BindState::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast(invoke_func); - } - - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); - } - - R Run(typename cef_internal::CallbackParamTraits::ForwardType a1, - typename cef_internal::CallbackParamTraits::ForwardType a2) const { - PolymorphicInvoke f = - reinterpret_cast(polymorphic_invoke_); - - return f(bind_state_.get(), cef_internal::CallbackForward(a1), - cef_internal::CallbackForward(a2)); - } + using ResultType = R; + using RunType = R(Args...); + using PolymorphicInvoke = R (*)(cef_internal::BindStateBase*, + cef_internal::PassingType...); - private: - typedef R (*PolymorphicInvoke)( - cef_internal::BindStateBase*, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType); -}; + constexpr RepeatingCallback() = default; + RepeatingCallback(std::nullptr_t) = delete; -template -class Callback : public cef_internal::CallbackBase { - public: - typedef R(RunType)(A1, A2, A3); + explicit RepeatingCallback(cef_internal::BindStateBase* bind_state) + : cef_internal::CallbackBaseCopyable(bind_state) {} - Callback() : CallbackBase(NULL) {} + // Copyable and movable. + RepeatingCallback(const RepeatingCallback&) = default; + RepeatingCallback& operator=(const RepeatingCallback&) = default; + RepeatingCallback(RepeatingCallback&&) noexcept = default; + RepeatingCallback& operator=(RepeatingCallback&&) noexcept = default; - // Note that this constructor CANNOT be explicit, and that Bind() CANNOT - // return the exact Callback<> type. See base/bind.h for details. - template - Callback( - cef_internal::BindState* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &cef_internal::BindState::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast(invoke_func); + bool operator==(const RepeatingCallback& other) const { + return EqualsInternal(other); } - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); + bool operator!=(const RepeatingCallback& other) const { + return !operator==(other); } - R Run(typename cef_internal::CallbackParamTraits::ForwardType a1, - typename cef_internal::CallbackParamTraits::ForwardType a2, - typename cef_internal::CallbackParamTraits::ForwardType a3) const { + R Run(Args... args) const& { PolymorphicInvoke f = - reinterpret_cast(polymorphic_invoke_); - - return f(bind_state_.get(), cef_internal::CallbackForward(a1), - cef_internal::CallbackForward(a2), - cef_internal::CallbackForward(a3)); + reinterpret_cast(this->polymorphic_invoke()); + return f(this->bind_state_.get(), std::forward(args)...); } - private: - typedef R (*PolymorphicInvoke)( - cef_internal::BindStateBase*, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType); -}; - -template -class Callback : public cef_internal::CallbackBase { - public: - typedef R(RunType)(A1, A2, A3, A4); - - Callback() : CallbackBase(NULL) {} - - // Note that this constructor CANNOT be explicit, and that Bind() CANNOT - // return the exact Callback<> type. See base/bind.h for details. - template - Callback( - cef_internal::BindState* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &cef_internal::BindState::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast(invoke_func); - } - - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); - } - - R Run(typename cef_internal::CallbackParamTraits::ForwardType a1, - typename cef_internal::CallbackParamTraits::ForwardType a2, - typename cef_internal::CallbackParamTraits::ForwardType a3, - typename cef_internal::CallbackParamTraits::ForwardType a4) const { - PolymorphicInvoke f = - reinterpret_cast(polymorphic_invoke_); - - return f(bind_state_.get(), cef_internal::CallbackForward(a1), - cef_internal::CallbackForward(a2), - cef_internal::CallbackForward(a3), - cef_internal::CallbackForward(a4)); - } - - private: - typedef R (*PolymorphicInvoke)( - cef_internal::BindStateBase*, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType); -}; - -template -class Callback : public cef_internal::CallbackBase { - public: - typedef R(RunType)(A1, A2, A3, A4, A5); - - Callback() : CallbackBase(NULL) {} - - // Note that this constructor CANNOT be explicit, and that Bind() CANNOT - // return the exact Callback<> type. See base/bind.h for details. - template - Callback( - cef_internal::BindState* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &cef_internal::BindState::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast(invoke_func); - } - - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); - } - - R Run(typename cef_internal::CallbackParamTraits::ForwardType a1, - typename cef_internal::CallbackParamTraits::ForwardType a2, - typename cef_internal::CallbackParamTraits::ForwardType a3, - typename cef_internal::CallbackParamTraits::ForwardType a4, - typename cef_internal::CallbackParamTraits::ForwardType a5) const { + R Run(Args... args) && { + // Move the callback instance into a local variable before the invocation, + // that ensures the internal state is cleared after the invocation. + // It's not safe to touch |this| after the invocation, since running the + // bound function may destroy |this|. + RepeatingCallback cb = std::move(*this); PolymorphicInvoke f = - reinterpret_cast(polymorphic_invoke_); - - return f( - bind_state_.get(), cef_internal::CallbackForward(a1), - cef_internal::CallbackForward(a2), cef_internal::CallbackForward(a3), - cef_internal::CallbackForward(a4), cef_internal::CallbackForward(a5)); + reinterpret_cast(cb.polymorphic_invoke()); + return f(std::move(cb).bind_state_.get(), std::forward(args)...); + } + + // Then() returns a new RepeatingCallback that receives the same arguments as + // |this|, and with the return type of |then|. The + // returned callback will: + // 1) Run the functor currently bound to |this| callback. + // 2) Run the |then| callback with the result from step 1 as its single + // argument. + // 3) Return the value from running the |then| callback. + // + // If called on an rvalue (e.g. std::move(cb).Then(...)), this method + // generates a callback that is a replacement for `this`. Therefore, `this` + // will be consumed and reset to a null callback to ensure the + // originally-bound functor will be run at most once. + template + RepeatingCallback Then( + RepeatingCallback then) const& { + CHECK(then); + return BindRepeating( + cef_internal::ThenHelper< + RepeatingCallback, + RepeatingCallback>::CreateTrampoline(), + *this, std::move(then)); + } + + template + RepeatingCallback Then( + RepeatingCallback then) && { + CHECK(then); + return BindRepeating( + cef_internal::ThenHelper< + RepeatingCallback, + RepeatingCallback>::CreateTrampoline(), + std::move(*this), std::move(then)); } - - private: - typedef R (*PolymorphicInvoke)( - cef_internal::BindStateBase*, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType); }; -template -class Callback : public cef_internal::CallbackBase { - public: - typedef R(RunType)(A1, A2, A3, A4, A5, A6); - - Callback() : CallbackBase(NULL) {} - - // Note that this constructor CANNOT be explicit, and that Bind() CANNOT - // return the exact Callback<> type. See base/bind.h for details. - template - Callback( - cef_internal::BindState* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &cef_internal::BindState::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast(invoke_func); - } - - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); - } - - R Run(typename cef_internal::CallbackParamTraits::ForwardType a1, - typename cef_internal::CallbackParamTraits::ForwardType a2, - typename cef_internal::CallbackParamTraits::ForwardType a3, - typename cef_internal::CallbackParamTraits::ForwardType a4, - typename cef_internal::CallbackParamTraits::ForwardType a5, - typename cef_internal::CallbackParamTraits::ForwardType a6) const { - PolymorphicInvoke f = - reinterpret_cast(polymorphic_invoke_); - - return f( - bind_state_.get(), cef_internal::CallbackForward(a1), - cef_internal::CallbackForward(a2), cef_internal::CallbackForward(a3), - cef_internal::CallbackForward(a4), cef_internal::CallbackForward(a5), - cef_internal::CallbackForward(a6)); - } - - private: - typedef R (*PolymorphicInvoke)( - cef_internal::BindStateBase*, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType); -}; - -template -class Callback - : public cef_internal::CallbackBase { - public: - typedef R(RunType)(A1, A2, A3, A4, A5, A6, A7); - - Callback() : CallbackBase(NULL) {} - - // Note that this constructor CANNOT be explicit, and that Bind() CANNOT - // return the exact Callback<> type. See base/bind.h for details. - template - Callback( - cef_internal::BindState* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &cef_internal::BindState::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast(invoke_func); - } - - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); - } - - R Run(typename cef_internal::CallbackParamTraits::ForwardType a1, - typename cef_internal::CallbackParamTraits::ForwardType a2, - typename cef_internal::CallbackParamTraits::ForwardType a3, - typename cef_internal::CallbackParamTraits::ForwardType a4, - typename cef_internal::CallbackParamTraits::ForwardType a5, - typename cef_internal::CallbackParamTraits::ForwardType a6, - typename cef_internal::CallbackParamTraits::ForwardType a7) const { - PolymorphicInvoke f = - reinterpret_cast(polymorphic_invoke_); - - return f( - bind_state_.get(), cef_internal::CallbackForward(a1), - cef_internal::CallbackForward(a2), cef_internal::CallbackForward(a3), - cef_internal::CallbackForward(a4), cef_internal::CallbackForward(a5), - cef_internal::CallbackForward(a6), cef_internal::CallbackForward(a7)); - } - - private: - typedef R (*PolymorphicInvoke)( - cef_internal::BindStateBase*, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType, - typename cef_internal::CallbackParamTraits::ForwardType); -}; - -// Syntactic sugar to make Callbacks easier to declare since it -// will be used in a lot of APIs with delayed execution. -typedef Callback Closure; - } // namespace base #endif // !USING_CHROMIUM_INCLUDES diff --git a/include/base/cef_callback_forward.h b/include/base/cef_callback_forward.h index d604d7c..2d22774 100644 --- a/include/base/cef_callback_forward.h +++ b/include/base/cef_callback_forward.h @@ -32,14 +32,9 @@ #define INCLUDE_BASE_CEF_CALLBACK_FORWARD_H_ #pragma once -#if defined(BASE_CALLBACK_FORWARD_H_) -// Do nothing if the Chromium header has already been included. -// This can happen in cases where Chromium code is used directly by the -// client application. When using Chromium code directly always include -// the Chromium header first to avoid type conflicts. -#elif defined(USING_CHROMIUM_INCLUDES) +#if defined(USING_CHROMIUM_INCLUDES) // When building CEF include the Chromium header directly. -#include "base/callback_forward.h" +#include "base/functional/callback_forward.h" #else // !USING_CHROMIUM_INCLUDES // The following is substantially similar to the Chromium implementation. // If the Chromium implementation diverges the below implementation should be @@ -47,10 +42,19 @@ namespace base { -template -class Callback; +template +class OnceCallback; -typedef Callback Closure; +template +class RepeatingCallback; + +/// +/// Syntactic sugar to make OnceClosure and RepeatingClosure +/// easier to declare since they will be used in a lot of APIs with delayed +/// execution. +/// +using OnceClosure = OnceCallback; +using RepeatingClosure = RepeatingCallback; } // namespace base diff --git a/include/base/cef_callback_helpers.h b/include/base/cef_callback_helpers.h index ebe074a..5e38644 100644 --- a/include/base/cef_callback_helpers.h +++ b/include/base/cef_callback_helpers.h @@ -32,60 +32,228 @@ // are implemented using templates, with a class per callback signature, adding // methods to Callback<> itself is unattractive (lots of extra code gets // generated). Instead, consider adding methods here. -// -// ResetAndReturn(&cb) is like cb.Reset() but allows executing a callback (via a -// copy) after the original callback is Reset(). This can be handy if Run() -// reads/writes the variable holding the Callback. #ifndef CEF_INCLUDE_BASE_CEF_CALLBACK_HELPERS_H_ #define CEF_INCLUDE_BASE_CEF_CALLBACK_HELPERS_H_ #pragma once -#if defined(BASE_CALLBACK_HELPERS_H_) -// Do nothing if the Chromium header has already been included. -// This can happen in cases where Chromium code is used directly by the -// client application. When using Chromium code directly always include -// the Chromium header first to avoid type conflicts. -#elif defined(USING_CHROMIUM_INCLUDES) +#if defined(USING_CHROMIUM_INCLUDES) // When building CEF include the Chromium header directly. -#include "base/callback_helpers.h" +#include "base/functional/callback_helpers.h" #else // !USING_CHROMIUM_INCLUDES // The following is substantially similar to the Chromium implementation. // If the Chromium implementation diverges the below implementation should be // updated to match. -#include "include/base/cef_basictypes.h" -#include "include/base/cef_build.h" +#include +#include +#include +#include + +#include "include/base/cef_bind.h" #include "include/base/cef_callback.h" -#include "include/base/cef_macros.h" +#include "include/base/cef_logging.h" namespace base { -template -base::Callback ResetAndReturn(base::Callback* cb) { - base::Callback ret(*cb); - cb->Reset(); - return ret; +namespace internal { + +template +struct IsBaseCallbackImpl : std::false_type {}; + +template +struct IsBaseCallbackImpl> : std::true_type {}; + +template +struct IsBaseCallbackImpl> : std::true_type {}; + +template +struct IsOnceCallbackImpl : std::false_type {}; + +template +struct IsOnceCallbackImpl> : std::true_type {}; + +} // namespace internal + +/// +/// IsBaseCallback::value is true when T is any of the Closure or Callback +/// family of types. +/// +template +using IsBaseCallback = internal::IsBaseCallbackImpl>; + +/// +/// IsOnceCallback::value is true when T is a OnceClosure or OnceCallback +/// type. +/// +template +using IsOnceCallback = internal::IsOnceCallbackImpl>; + +/// +/// SFINAE friendly enabler allowing to overload methods for both Repeating and +/// OnceCallbacks. +/// +/// Usage: +///
+///   template