From e7c5ae0beb17fc8c9e4b4ff548bfb30fe49b49f8 Mon Sep 17 00:00:00 2001 From: William Miles Date: Sun, 20 Nov 2022 11:26:34 +1100 Subject: [PATCH] Removed noexcept as I don't feel I sufficiently understand the implications of its use. Modified Store with a CRTP tag to prevent base clase pointer misuse. --- .vscode/tasks.json | 26 ++++++++++++++++++++ Navmesher/esx_reader.cpp | 16 ++++++------- Navmesher/esx_reader.hpp | 46 ++++++++++++++++++------------------ Navmesher/esx_reader_lut.cpp | 12 +++++----- Navmesher/utility.hpp | 20 +++++++++------- 5 files changed, 74 insertions(+), 46 deletions(-) create mode 100644 .vscode/tasks.json diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..f97e9e6 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,26 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "msbuild", + "args": [ + // Ask msbuild to generate full paths for file names. + "/property:GenerateFullPaths=true", + "/t:build", + // Do not generate summary otherwise it leads to duplicate errors in Problems panel + "/consoleloggerparameters:NoSummary" + ], + "group": "build", + "presentation": { + // Reveal the output only if unrecognized errors occur. + "reveal": "silent" + }, + // Use the standard MS compiler pattern to detect errors, warnings and infos + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Navmesher/esx_reader.cpp b/Navmesher/esx_reader.cpp index 214ce6a..fc4543d 100644 --- a/Navmesher/esx_reader.cpp +++ b/Navmesher/esx_reader.cpp @@ -9,42 +9,42 @@ Node read_unknown_record(std::istream &in); return read_header_impl(in); } -[[nodiscard]] std::size_t data_size(const RecordHeader& header) noexcept +[[nodiscard]] std::size_t data_size(const RecordHeader& header) { return header.size; } -[[nodiscard]] std::size_t data_size(const GroupHeader& header) noexcept +[[nodiscard]] std::size_t data_size(const GroupHeader& header) { return header.size - header_size; } -[[nodiscard]] std::streamsize data_ssize(const RecordHeader& header) noexcept +[[nodiscard]] std::streamsize data_ssize(const RecordHeader& header) { return static_cast(data_size(header)); } -[[nodiscard]] std::streamsize data_ssize(const GroupHeader& header) noexcept +[[nodiscard]] std::streamsize data_ssize(const GroupHeader& header) { return static_cast(data_size(header)); } -[[nodiscard]] std::size_t node_size(const RecordNode& node) noexcept +[[nodiscard]] std::size_t node_size(const RecordNode& node) { return node.header.size + header_size; } -[[nodiscard]] std::size_t node_size(const GroupNode& node) noexcept +[[nodiscard]] std::size_t node_size(const GroupNode& node) { return node.header.size; } -[[nodiscard]] std::streamsize node_ssize(const RecordNode& node) noexcept +[[nodiscard]] std::streamsize node_ssize(const RecordNode& node) { return static_cast(node_size(node)); } -[[nodiscard]] std::streamsize node_ssize(const GroupNode& node) noexcept +[[nodiscard]] std::streamsize node_ssize(const GroupNode& node) { return static_cast(node_size(node)); } diff --git a/Navmesher/esx_reader.hpp b/Navmesher/esx_reader.hpp index 2b99ef6..c48b5a9 100644 --- a/Navmesher/esx_reader.hpp +++ b/Navmesher/esx_reader.hpp @@ -58,21 +58,21 @@ enum class RecordType { // Aggregate types // -struct FourCC : utility::Store { }; -struct FormID : utility::Store { }; -struct Timestamp : utility::Store { }; -struct VCInfo : utility::Store { }; +struct FourCC : utility::Store { }; +struct FormID : utility::Store { }; +struct Timestamp : utility::Store { }; +struct VCInfo : utility::Store { }; struct Flag { RecordType type; unsigned bit; - friend constexpr auto operator<=>(const Flag &, const Flag &) noexcept = default; + friend constexpr auto operator<=>(const Flag &, const Flag &) = default; }; struct RefrFlag { RecordType refr_type; unsigned bit; - friend constexpr auto operator<=>(const RefrFlag &, const RefrFlag &) noexcept = default; + friend constexpr auto operator<=>(const RefrFlag &, const RefrFlag &) = default; }; struct UnknownHeader { @@ -85,14 +85,14 @@ struct GroupHeader { int16_t y, x; }; - struct TopType : utility::Store { }; - struct ParentWorld : utility::Store { }; - struct BlockNumber : utility::Store { }; - struct SubBlockNumber : utility::Store { }; - struct BlockCoord : utility::Store { }; - struct SubBlockCoord : utility::Store { }; - struct ParentCell : utility::Store { }; - struct ParentDialogue : utility::Store { }; + struct TopType : utility::Store { }; + struct ParentWorld : utility::Store { }; + struct BlockNumber : utility::Store { }; + struct SubBlockNumber : utility::Store { }; + struct BlockCoord : utility::Store { }; + struct SubBlockCoord : utility::Store { }; + struct ParentCell : utility::Store { }; + struct ParentDialogue : utility::Store { }; union GroupLabel { TopType top_type; @@ -115,8 +115,8 @@ struct GroupHeader { }; struct RecordHeader { - struct Flags : utility::Store { }; - struct Version : utility::Store { }; + struct Flags : utility::Store { }; + struct Version : utility::Store { }; FourCC type; uint32_t size; @@ -153,18 +153,18 @@ struct RecordNode { // Free functions // -[[nodiscard]] std::optional group_type_to_name(GroupType group_type) noexcept; -[[nodiscard]] std::optional record_type_to_fourcc(RecordType record_type) noexcept; -[[nodiscard]] std::optional fourcc_to_record_type(FourCC fourcc) noexcept; -[[nodiscard]] std::optional record_type_to_name(RecordType record_type) noexcept; -[[nodiscard]] std::optional flag_to_description(Flag flag) noexcept; -[[nodiscard]] std::optional refr_flag_to_description(RefrFlag refr_flag) noexcept; +[[nodiscard]] std::optional group_type_to_name(GroupType group_type); +[[nodiscard]] std::optional record_type_to_fourcc(RecordType record_type); +[[nodiscard]] std::optional fourcc_to_record_type(FourCC fourcc); +[[nodiscard]] std::optional record_type_to_name(RecordType record_type); +[[nodiscard]] std::optional flag_to_description(Flag flag); +[[nodiscard]] std::optional refr_flag_to_description(RefrFlag refr_flag); [[nodiscard]] Header read_header(std::istream &in); [[nodiscard]] RootNode read_esx(std::istream &in, std::size_t file_size); // Convert a compatible C string to a FourCC (e.g. "LITR") -static consteval FourCC fourcc_from_cstr(const char(&a)[5]) noexcept +static consteval FourCC fourcc_from_cstr(const char(&a)[5]) { char temp[4] = { a[0], a[1], a[2], a[3] }; return std::bit_cast(temp); diff --git a/Navmesher/esx_reader_lut.cpp b/Navmesher/esx_reader_lut.cpp index 60dcd08..4069847 100644 --- a/Navmesher/esx_reader_lut.cpp +++ b/Navmesher/esx_reader_lut.cpp @@ -658,31 +658,31 @@ static constexpr auto flag_description_map = utility::map_to_soa(flag_descriptio static constexpr auto refr_flag_description_map_std = utility::array_builtin_to_std(refr_flag_description_map_builtin); static constexpr auto refr_flag_description_map = utility::map_to_soa(refr_flag_description_map_std); -[[nodiscard]] std::optional esxr::group_type_to_name(GroupType group_type) noexcept +[[nodiscard]] std::optional esxr::group_type_to_name(GroupType group_type) { return utility::soa_first_to_second(group_type_name_map, group_type); } -[[nodiscard]] std::optional esxr::record_type_to_fourcc(RecordType record_type) noexcept +[[nodiscard]] std::optional esxr::record_type_to_fourcc(RecordType record_type) { return utility::soa_first_to_second(record_type_fourcc_map, record_type); } -[[nodiscard]] std::optional esxr::fourcc_to_record_type(FourCC fourcc) noexcept +[[nodiscard]] std::optional esxr::fourcc_to_record_type(FourCC fourcc) { return utility::soa_second_to_first(record_type_fourcc_map, fourcc); } -[[nodiscard]] std::optional esxr::record_type_to_name(RecordType record_type) noexcept +[[nodiscard]] std::optional esxr::record_type_to_name(RecordType record_type) { return utility::soa_first_to_second(record_type_name_map, record_type); } -[[nodiscard]] std::optional esxr::flag_to_description(Flag flag) noexcept +[[nodiscard]] std::optional esxr::flag_to_description(Flag flag) { return utility::soa_first_to_second(flag_description_map, flag); } -[[nodiscard]] std::optional esxr::refr_flag_to_description(RefrFlag refr_flag) noexcept +[[nodiscard]] std::optional esxr::refr_flag_to_description(RefrFlag refr_flag) { return utility::soa_first_to_second(refr_flag_description_map, refr_flag); } \ No newline at end of file diff --git a/Navmesher/utility.hpp b/Navmesher/utility.hpp index bb85365..292aacf 100644 --- a/Navmesher/utility.hpp +++ b/Navmesher/utility.hpp @@ -16,17 +16,19 @@ T::size_type index_of(const T &container, typename T::const_iterator &iter) } // This is a base class for a generic store for some value that can be represented by -// type T but should not be type checked as type T, but rather some more constrained class. -template +// type Type but should not be type checked as type Type, but rather some more constrained class. +// CRTP is the derived class, and is used as a tag to prevent having Store as a base class to +// multiple derived types. +template struct Store { - static_assert(std::is_trivial_v); - T value; - friend constexpr auto operator<=>(const Store &, const Store &) noexcept = default; + static_assert(std::is_trivial_v); + Type value; + friend constexpr auto operator<=>(const Store &, const Store &) = default; }; // Convert a builtin array to a std::array template -constexpr std::array array_builtin_to_std(const T(&builtin)[N]) noexcept +constexpr std::array array_builtin_to_std(const T(&builtin)[N]) { std::array array; std::copy(std::cbegin(builtin), std::cend(builtin), array.begin()); @@ -35,7 +37,7 @@ constexpr std::array array_builtin_to_std(const T(&builtin)[N]) noexcept // Convert a std::array of std::pairs to a std::pair of std::arrays template -constexpr std::pair, std::array> map_to_soa(std::array, N> map) noexcept +constexpr std::pair, std::array> map_to_soa(std::array, N> map) { std::array first; std::array second; @@ -47,7 +49,7 @@ constexpr std::pair, std::array> map_to_soa(std: } template -constexpr std::optional soa_first_to_second(const std::pair, std::array> &soa, const First &first) noexcept +constexpr std::optional soa_first_to_second(const std::pair, std::array> &soa, const First &first) { auto lhs = std::find(soa.first.cbegin(), soa.first.cend(), first); if (lhs == soa.first.cend()) @@ -57,7 +59,7 @@ constexpr std::optional soa_first_to_second(const std::pair -constexpr std::optional soa_second_to_first(const std::pair, std::array> &soa, const Second &second) noexcept +constexpr std::optional soa_second_to_first(const std::pair, std::array> &soa, const Second &second) { auto lhs = std::find(soa.second.cbegin(), soa.second.cend(), second); if (lhs == soa.second.cend())