From bb75f98d5dd12c8b202fe406b5c8b113b475d5c2 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sat, 1 Jan 2022 13:20:34 +0000 Subject: [PATCH] Experimentation with C++17 compatibilty. Mainly an exercise in rewrting coroutine code in boost::coroutine2. Interesting! --- Gaming/src/Game.cpp | 6 ++- M6502/HarteTest_6502/checker_t.cpp | 4 ++ M6502/HarteTest_6502/opcode_test_suite_t.cpp | 7 ++++ M6502/HarteTest_6502/opcode_test_suite_t.h | 10 ++++- M6502/HarteTest_6502/parser_t.h | 4 ++ .../HarteTest_6502/processor_test_suite_t.cpp | 8 ++++ M6502/HarteTest_6502/processor_test_suite_t.h | 10 ++++- M6502/HarteTest_6502/stdafx.h | 8 +++- M6502/HarteTest_6502/tests.cpp | 37 +++++++++++++++++++ Z80/inc/Profiler.h | 24 ++++++++++++ inc/Register.h | 6 +++ src/stdafx.h | 1 - 12 files changed, 120 insertions(+), 5 deletions(-) diff --git a/Gaming/src/Game.cpp b/Gaming/src/Game.cpp index eb5a98e..a3a9c4e 100644 --- a/Gaming/src/Game.cpp +++ b/Gaming/src/Game.cpp @@ -168,7 +168,7 @@ void Game::removeJoystick(SDL_Event& e) { const auto which = e.jdevice.which; const auto found = m_gameControllers.find(which); SDL_assert(found != m_gameControllers.end()); - auto controller = found->second; + auto& controller = found->second; const auto joystickId = controller->getJoystickId(); m_mappedControllers.erase(joystickId); m_gameControllers.erase(which); @@ -181,7 +181,11 @@ void Game::addJoystick(SDL_Event& e) { auto controller = std::make_shared(which); const auto joystickId = controller->getJoystickId(); m_gameControllers[which] = controller; +#if __cplusplus >= 202002L SDL_assert(m_mappedControllers.contains(joystickId)); +#else + SDL_assert(m_mappedControllers.find(joystickId) != m_mappedControllers.end()); +#endif m_mappedControllers[joystickId] = which; SDL_Log("Joystick device %d added (%zd controllers)", which, m_gameControllers.size()); } diff --git a/M6502/HarteTest_6502/checker_t.cpp b/M6502/HarteTest_6502/checker_t.cpp index f4c196b..6c51dd5 100644 --- a/M6502/HarteTest_6502/checker_t.cpp +++ b/M6502/HarteTest_6502/checker_t.cpp @@ -210,7 +210,11 @@ void checker_t::check(test_t current) { const auto pc = cpu.PC().word; const auto start_opcode = runner().peek(pc); +#if __cplusplus >= 202002L m_undocumented = m_undocumented_opcodes.contains(start_opcode); +#else + m_undocumented = m_undocumented_opcodes.find(start_opcode) != m_undocumented_opcodes.end(); +#endif if (undocumented()) { m_valid = false; m_messages.push_back("Undocumented"); diff --git a/M6502/HarteTest_6502/opcode_test_suite_t.cpp b/M6502/HarteTest_6502/opcode_test_suite_t.cpp index 0a19628..8c9000c 100644 --- a/M6502/HarteTest_6502/opcode_test_suite_t.cpp +++ b/M6502/HarteTest_6502/opcode_test_suite_t.cpp @@ -4,7 +4,14 @@ opcode_test_suite_t::opcode_test_suite_t(const std::string path) noexcept : parser_t(path) {} +#if __cplusplus >= 202002L EightBit::co_generator_t opcode_test_suite_t::generator() { for (const auto element : *this) co_yield test_t(element); } +#else +void opcode_test_suite_t::generator(boost::coroutines2::coroutine::push_type& sink) { + for (const auto element : *this) + sink(test_t(element)); +} +#endif \ No newline at end of file diff --git a/M6502/HarteTest_6502/opcode_test_suite_t.h b/M6502/HarteTest_6502/opcode_test_suite_t.h index acccf0a..eed3a7a 100644 --- a/M6502/HarteTest_6502/opcode_test_suite_t.h +++ b/M6502/HarteTest_6502/opcode_test_suite_t.h @@ -2,7 +2,11 @@ #include -#include +#if __cplusplus >= 202002L +# include +#else +# include +#endif #include "parser_t.h" #include "test_t.h" @@ -18,5 +22,9 @@ public: [[nodiscard]] auto begin() const noexcept { return array().begin(); } [[nodiscard]] auto end() const noexcept { return array().end(); } +#if __cplusplus >= 202002L [[nodiscard]] EightBit::co_generator_t generator(); +#else + void generator(boost::coroutines2::coroutine::push_type& sink); +#endif }; diff --git a/M6502/HarteTest_6502/parser_t.h b/M6502/HarteTest_6502/parser_t.h index 8a383ba..122335e 100644 --- a/M6502/HarteTest_6502/parser_t.h +++ b/M6502/HarteTest_6502/parser_t.h @@ -19,7 +19,11 @@ public: parser_t() noexcept {} parser_t(std::string path) noexcept; +#if __cplusplus >= 202002L [[nodiscard]] constexpr std::string_view path() const noexcept { return m_path; } +#else + [[nodiscard]] std::string_view path() const noexcept { return m_path; } +#endif [[nodiscard]] const auto raw() const noexcept { return m_raw; } virtual void load(); diff --git a/M6502/HarteTest_6502/processor_test_suite_t.cpp b/M6502/HarteTest_6502/processor_test_suite_t.cpp index 2a06842..29f6918 100644 --- a/M6502/HarteTest_6502/processor_test_suite_t.cpp +++ b/M6502/HarteTest_6502/processor_test_suite_t.cpp @@ -7,8 +7,16 @@ processor_test_suite_t::processor_test_suite_t(std::string location) noexcept : m_location(location) { } +#if __cplusplus >= 202002L EightBit::co_generator_t processor_test_suite_t::generator() { std::filesystem::path directory = location(); for (const auto& entry : std::filesystem::directory_iterator{ directory }) co_yield opcode_test_suite_t(entry.path().string()); } +#else +void processor_test_suite_t::generator(boost::coroutines2::coroutine::push_type& sink) { + std::filesystem::path directory = location(); + for (const auto& entry : std::filesystem::directory_iterator{ directory }) + sink(opcode_test_suite_t(entry.path().string())); +} +#endif diff --git a/M6502/HarteTest_6502/processor_test_suite_t.h b/M6502/HarteTest_6502/processor_test_suite_t.h index 3e00434..309388f 100644 --- a/M6502/HarteTest_6502/processor_test_suite_t.h +++ b/M6502/HarteTest_6502/processor_test_suite_t.h @@ -3,7 +3,11 @@ #include #include -#include +#if __cplusplus >= 202002L +# include +#else +# include +#endif #include "opcode_test_suite_t.h" @@ -16,5 +20,9 @@ public: std::string_view location() const noexcept { return m_location; } +#if __cplusplus >= 202002L [[nodiscard]] EightBit::co_generator_t generator(); +#else + void generator(boost::coroutines2::coroutine::push_type& sink); +#endif }; diff --git a/M6502/HarteTest_6502/stdafx.h b/M6502/HarteTest_6502/stdafx.h index 6a06d44..a792a1e 100644 --- a/M6502/HarteTest_6502/stdafx.h +++ b/M6502/HarteTest_6502/stdafx.h @@ -21,6 +21,12 @@ #include #include #include -#include + +#if __cplusplus >= 202002L +# include +#else +# include +# include +#endif #include "simdjson/simdjson.h" diff --git a/M6502/HarteTest_6502/tests.cpp b/M6502/HarteTest_6502/tests.cpp index 7d6a38b..abc3a04 100644 --- a/M6502/HarteTest_6502/tests.cpp +++ b/M6502/HarteTest_6502/tests.cpp @@ -4,6 +4,10 @@ #include #include +#if __cplusplus < 202002L +# include +#endif + #include "TestRunner.h" #include "checker_t.h" #include "test_t.h" @@ -26,6 +30,8 @@ int main() { checker_t checker(runner); checker.initialise(); +#if __cplusplus >= 202002L + processor_test_suite_t m6502_tests(directory); auto opcode_generator = m6502_tests.generator(); while (opcode_generator) { @@ -56,6 +62,37 @@ int main() { } } +#else + + processor_test_suite_t m6502_tests(directory); + boost::coroutines2::coroutine::pull_type opcodes(boost::bind(&processor_test_suite_t::generator, &m6502_tests, _1)); + for (auto& opcode : opcodes) { + + const auto path = std::filesystem::path(opcode.path()); + std::cout << "Processing: " << path.filename() << "\n"; + opcode.load(); + + boost::coroutines2::coroutine::pull_type tests(boost::bind(&opcode_test_suite_t::generator, &opcode, _1)); + for (auto& test : tests) { + + checker.check(test); + + if (checker.invalid()) { + ++invalid_opcode_count; + if (checker.unimplemented()) + ++unimplemented_opcode_count; + if (checker.undocumented()) + ++undocumented_opcode_count; + std::cout << "** Failed: " << test.name() << "\n"; + for (const auto& message : checker.messages()) + std::cout << "**** " << message << "\n"; + break; + } + } + } + +#endif + const auto finish_time = std::chrono::steady_clock::now(); const auto elapsed_time = finish_time - start_time; const auto seconds = std::chrono::duration_cast>(elapsed_time).count(); diff --git a/Z80/inc/Profiler.h b/Z80/inc/Profiler.h index 5f7975f..ad0a8b5 100644 --- a/Z80/inc/Profiler.h +++ b/Z80/inc/Profiler.h @@ -27,6 +27,8 @@ namespace EightBit { [[nodiscard]] constexpr const auto& instructions() const { return m_instructions; } [[nodiscard]] constexpr const auto& addresses() const { return m_addresses; } +#if __cplusplus >= 202002L + [[nodiscard]] constexpr auto instructions_available() const noexcept { const auto found = std::find_if( instructions().begin(), instructions().end(), @@ -45,6 +47,28 @@ namespace EightBit { return instructions_available() || addresses_available(); } +#else + + [[nodiscard]] auto instructions_available() const noexcept { + const auto found = std::find_if( + instructions().begin(), instructions().end(), + [](const auto& value) { return value != 0; }); + return found != instructions().end(); + } + + [[nodiscard]] auto addresses_available() const noexcept { + const auto found = std::find_if( + addresses().begin(), addresses().end(), + [](const auto& value) { return value != 0; }); + return found != addresses().end(); + } + + [[nodiscard]] auto available() const noexcept { + return instructions_available() || addresses_available(); + } + +#endif + void dumpInstructionProfiles() const; void dumpAddressProfiles() const; }; diff --git a/inc/Register.h b/inc/Register.h index 89cc47e..2f67a4c 100644 --- a/inc/Register.h +++ b/inc/Register.h @@ -74,9 +74,15 @@ namespace EightBit { return lhs.word == rhs.word; } +#if __cplusplus >= 202002L [[nodiscard]] constexpr auto operator<=>(const register16_t lhs, const register16_t rhs) noexcept { return lhs.word <=> rhs.word; } +#else + [[nodiscard]] constexpr inline auto operator!=(const register16_t lhs, const register16_t rhs) noexcept { + return lhs.word != rhs.word; + } +#endif [[nodiscard]] constexpr inline auto operator+(register16_t lhs, const register16_t rhs) noexcept { lhs += rhs; diff --git a/src/stdafx.h b/src/stdafx.h index 2f99750..3442d95 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -3,7 +3,6 @@ #endif #include -#include #include #include #include