From da398465144677407340f22229c6df8627b551fb Mon Sep 17 00:00:00 2001 From: Kp Date: Sun, 14 May 2023 18:41:36 +0000 Subject: [PATCH] Remove unnecessary pointer in savegame_newmenu_items The pointer is only used by the constructor, so there is no need to store it in the object. Rework the allocation of the trailing storage to avoid the use of placement new on a uint8_t[]. --- similar/main/state.cpp | 46 +++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/similar/main/state.cpp b/similar/main/state.cpp index 54472e313..19a08f3be 100644 --- a/similar/main/state.cpp +++ b/similar/main/state.cpp @@ -162,7 +162,6 @@ struct savegame_newmenu_items }; static constexpr unsigned decorative_item_count = 1; using imenu_description_buffers_array = std::array, NUM_SAVES>; - imenu_description_buffers_array *const user_entered_savegame_descriptions; d_game_unique_state::savegame_description *const caller_savegame_description; d_game_unique_state::savegame_file_path &savegame_file_path; enumerated_array savegame_file_paths; @@ -182,7 +181,7 @@ struct savegame_newmenu_items * savegame slot in use, return true. This does not test whether * there currently exists a savegame in the specified slot. */ - static unsigned valid_savegame_index(void *const user_entered_savegame_descriptions, const d_game_unique_state::save_slot selection) + static unsigned valid_savegame_index(const d_game_unique_state::savegame_description *const user_entered_savegame_descriptions, const d_game_unique_state::save_slot selection) { return user_entered_savegame_descriptions ? GameUniqueState.valid_save_slot(selection) @@ -190,7 +189,7 @@ struct savegame_newmenu_items } unsigned valid_savegame_index(const d_game_unique_state::save_slot selection) const { - return valid_savegame_index(user_entered_savegame_descriptions, selection); + return valid_savegame_index(caller_savegame_description, selection); } std::size_t get_count_valid_menuitem_entries(d_game_unique_state::savegame_description *const savegame_description) const { @@ -198,14 +197,30 @@ struct savegame_newmenu_items } }; -struct savegame_chooser_newmenu : savegame_newmenu_items, newmenu +struct savegame_chooser_newmenu final : savegame_newmenu_items, newmenu { + enum class trailing_storage_size : std::size_t + { + }; + static void *operator new(std::size_t bytes) = delete; + static void *operator new(std::size_t bytes, const trailing_storage_size extra_bytes) + { + return ::operator new(bytes + static_cast(extra_bytes)); + } + static void operator delete(void *p) + { + ::operator delete(p); + } + static void operator delete(void *p, trailing_storage_size) + { + ::operator delete(p); + } virtual window_event_result event_handler(const d_event &) override; static std::unique_ptr create(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path); private: void draw_handler(grs_canvas &canvas, const grs_bitmap &bmp); void draw_handler(); - savegame_chooser_newmenu(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *, d_game_unique_state::savegame_file_path &, imenu_description_buffers_array *); + savegame_chooser_newmenu(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *, d_game_unique_state::savegame_file_path &); d_game_unique_state::save_slot build_save_slot_from_citem() const { if (citem < decorative_item_count) @@ -216,18 +231,18 @@ private: std::unique_ptr savegame_chooser_newmenu::create(menu_subtitle caption, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path) { - std::unique_ptr p(savegame_description - /* request to create a "Save game" menu */ - ? reinterpret_cast(new typename std::aligned_union::type) - /* request to create a "Load game" menu */ - : reinterpret_cast(new typename std::aligned_union<0 /* no extra storage needed, and aligned_union will ensure the value is sufficient for the aligned type */, savegame_chooser_newmenu>::type) - ); - new (p.get()) savegame_chooser_newmenu(caption, src, savegame_description, savegame_file_path, savegame_description ? reinterpret_cast(p.get() + sizeof(savegame_chooser_newmenu)) : nullptr); - return std::unique_ptr(reinterpret_cast(p.release())); + /* If savegame_description is not nullptr, then this is a request to + * create a "Save game" menu. Otherwise, it is a request to create a + * "Load game" menu. + */ + const savegame_chooser_newmenu::trailing_storage_size extra_bytes{ + savegame_description ? sizeof(savegame_chooser_newmenu::imenu_description_buffers_array) : 0 + }; + return std::unique_ptr(new (extra_bytes) savegame_chooser_newmenu(caption, src, savegame_description, savegame_file_path)); } -savegame_chooser_newmenu::savegame_chooser_newmenu(menu_subtitle subtitle, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path, imenu_description_buffers_array *const user_entered_savegame_descriptions) : - savegame_newmenu_items(savegame_description, savegame_file_path, user_entered_savegame_descriptions), +savegame_chooser_newmenu::savegame_chooser_newmenu(menu_subtitle subtitle, grs_canvas &src, d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path) : + savegame_newmenu_items(savegame_description, savegame_file_path, savegame_description ? reinterpret_cast(this + 1) : nullptr), newmenu(menu_title{nullptr}, subtitle, menu_filename{nullptr}, tiny_mode_flag::normal, tab_processing_flag::ignore, adjusted_citem::create(unchecked_partial_range(m, get_count_valid_menuitem_entries(savegame_description)), decorative_item_count), src) { } @@ -975,7 +990,6 @@ uint8_t read_savegame_properties(const std::size_t savegame_index, d_game_unique } savegame_newmenu_items::savegame_newmenu_items(d_game_unique_state::savegame_description *const savegame_description, d_game_unique_state::savegame_file_path &savegame_file_path, imenu_description_buffers_array *const user_entered_savegame_descriptions) : - user_entered_savegame_descriptions(user_entered_savegame_descriptions), caller_savegame_description(savegame_description), savegame_file_path(savegame_file_path) {