diff --git a/EightBit.sln b/EightBit.sln index 9b0340b..a15a8c1 100644 --- a/EightBit.sln +++ b/EightBit.sln @@ -41,6 +41,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HarteTest_6502", "M6502\Har EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HarteTest_Z80", "Z80\HarteTest_Z80\HarteTest_Z80.vcxproj", "{93F0D716-A83D-4AFD-AF9D-4F947D1C9F02}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittest_EightBit", "unittest_EightBit\unittest_EightBit.vcxproj", "{7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -201,6 +203,14 @@ Global {93F0D716-A83D-4AFD-AF9D-4F947D1C9F02}.Release|x64.Build.0 = Release|x64 {93F0D716-A83D-4AFD-AF9D-4F947D1C9F02}.Release|x86.ActiveCfg = Release|Win32 {93F0D716-A83D-4AFD-AF9D-4F947D1C9F02}.Release|x86.Build.0 = Release|Win32 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}.Debug|x64.ActiveCfg = Debug|x64 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}.Debug|x64.Build.0 = Debug|x64 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}.Debug|x86.ActiveCfg = Debug|Win32 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}.Debug|x86.Build.0 = Debug|Win32 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}.Release|x64.ActiveCfg = Release|x64 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}.Release|x64.Build.0 = Release|x64 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}.Release|x86.ActiveCfg = Release|Win32 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/M6502/HarteTest_6502/TestRunner.cpp b/M6502/HarteTest_6502/TestRunner.cpp index 8683ce8..4723e07 100644 --- a/M6502/HarteTest_6502/TestRunner.cpp +++ b/M6502/HarteTest_6502/TestRunner.cpp @@ -3,10 +3,6 @@ TestRunner::TestRunner() {} -EightBit::MemoryMapping TestRunner::mapping(const uint16_t address) noexcept { - return { RAM(), 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; -} - void TestRunner::raisePOWER() noexcept { EightBit::Bus::raisePOWER(); CPU().raisePOWER(); diff --git a/M6502/HarteTest_6502/TestRunner.h b/M6502/HarteTest_6502/TestRunner.h index b6afd2e..28ad46c 100644 --- a/M6502/HarteTest_6502/TestRunner.h +++ b/M6502/HarteTest_6502/TestRunner.h @@ -8,9 +8,10 @@ class TestRunner final : public EightBit::Bus { private: EightBit::Ram m_ram = 0x10000; EightBit::MOS6502 m_cpu = { *this }; + EightBit::MemoryMapping m_mapping = { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; protected: - EightBit::MemoryMapping mapping(uint16_t address) noexcept final; + const EightBit::MemoryMapping& mapping(uint16_t address) noexcept final { return m_mapping; } public: TestRunner(); diff --git a/M6502/test/Board.h b/M6502/test/Board.h index 547c0cd..812d710 100644 --- a/M6502/test/Board.h +++ b/M6502/test/Board.h @@ -23,7 +23,7 @@ public: void initialise() noexcept final; protected: - virtual constexpr EightBit::MemoryMapping mapping(uint16_t address) noexcept final { + virtual constexpr const EightBit::MemoryMapping& mapping(uint16_t address) noexcept final { return m_mapping; } diff --git a/Z80/HarteTest_Z80/TestRunner.cpp b/Z80/HarteTest_Z80/TestRunner.cpp index 7e60a9d..c38b8cb 100644 --- a/Z80/HarteTest_Z80/TestRunner.cpp +++ b/Z80/HarteTest_Z80/TestRunner.cpp @@ -3,10 +3,6 @@ TestRunner::TestRunner() {} -EightBit::MemoryMapping TestRunner::mapping(const uint16_t address) noexcept { - return { RAM(), 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; -} - void TestRunner::raisePOWER() noexcept { EightBit::Bus::raisePOWER(); CPU().raisePOWER(); diff --git a/Z80/HarteTest_Z80/TestRunner.h b/Z80/HarteTest_Z80/TestRunner.h index af55c84..ef61d37 100644 --- a/Z80/HarteTest_Z80/TestRunner.h +++ b/Z80/HarteTest_Z80/TestRunner.h @@ -9,9 +9,10 @@ private: EightBit::Ram m_ram = 0x10000; EightBit::InputOutput m_ports; EightBit::Z80 m_cpu = { *this, m_ports }; + EightBit::MemoryMapping m_mapping = { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; protected: - EightBit::MemoryMapping mapping(uint16_t address) noexcept final; + const EightBit::MemoryMapping& mapping(uint16_t address) noexcept final { return m_mapping; } public: TestRunner(); diff --git a/Z80/test/Board.h b/Z80/test/Board.h index 22c71c9..b0d6a9a 100644 --- a/Z80/test/Board.h +++ b/Z80/test/Board.h @@ -24,7 +24,7 @@ public: void initialise() noexcept final; protected: - EightBit::MemoryMapping mapping(uint16_t address) noexcept final { + const EightBit::MemoryMapping& mapping(uint16_t address) noexcept final { return m_mapping; } diff --git a/inc/Bus.h b/inc/Bus.h index 336ced5..d804e9e 100644 --- a/inc/Bus.h +++ b/inc/Bus.h @@ -44,5 +44,6 @@ namespace EightBit { private: uint8_t m_data = Chip::Mask8; register16_t m_address = Chip::Mask16; + bool m_writing = false; }; } diff --git a/inc/Chip.h b/inc/Chip.h index 106ecde..7b6bd78 100644 --- a/inc/Chip.h +++ b/inc/Chip.h @@ -84,14 +84,14 @@ namespace EightBit { [[nodiscard]] static uint16_t constexpr makeWord(uint8_t low, uint8_t high) noexcept { return promoteByte(high) | low; } - [[nodiscard]] static constexpr auto highNibble(const int value) noexcept { return value >> 4; } - [[nodiscard]] static constexpr auto lowNibble(const int value) noexcept { return value & Mask4; } + [[nodiscard]] static constexpr auto highNibble(const uint8_t value) noexcept { return value >> 4; } + [[nodiscard]] static constexpr auto lowNibble(const uint8_t value) noexcept { return value & Mask4; } - [[nodiscard]] static constexpr auto higherNibble(const int value) noexcept { return value & 0xf0; } - [[nodiscard]] static constexpr auto lowerNibble(const int value) noexcept { return lowNibble(value); } + [[nodiscard]] static constexpr auto higherNibble(const uint8_t value) noexcept { return value & 0xf0; } + [[nodiscard]] static constexpr auto lowerNibble(const uint8_t value) noexcept { return lowNibble(value); } - [[nodiscard]] static constexpr auto promoteNibble(const int value) noexcept { return value << 4; } - [[nodiscard]] static constexpr auto demoteNibble(const int value) noexcept { return highNibble(value); } + [[nodiscard]] static constexpr auto promoteNibble(const uint8_t value) noexcept { return lowByte(value << 4); } + [[nodiscard]] static constexpr auto demoteNibble(const uint8_t value) noexcept { return highNibble(value); } [[nodiscard]] static auto countBits(unsigned value) noexcept { #if defined(_MSC_VER) diff --git a/inc/Mapper.h b/inc/Mapper.h index f712145..4e6e0e0 100644 --- a/inc/Mapper.h +++ b/inc/Mapper.h @@ -8,6 +8,6 @@ namespace EightBit { class Mapper { public: virtual ~Mapper() noexcept = default; - [[nodiscard]] virtual MemoryMapping mapping(uint16_t address) noexcept = 0; + [[nodiscard]] virtual const MemoryMapping& mapping(uint16_t address) noexcept = 0; }; } diff --git a/inc/MemoryMapping.h b/inc/MemoryMapping.h index 6ccd3fa..e3a173e 100644 --- a/inc/MemoryMapping.h +++ b/inc/MemoryMapping.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include "Chip.h" namespace EightBit { @@ -8,14 +10,38 @@ namespace EightBit { class Memory; struct MemoryMapping final { + private: + static const int minimum = std::numeric_limits::min(); + static const int maximum = std::numeric_limits::max(); + std::array _offsets; + + constexpr auto create_offset(uint16_t address) const noexcept { + return (address - begin) & mask; + } + + public: enum class AccessLevel { Unknown, ReadOnly, WriteOnly, ReadWrite }; - constexpr auto offset(uint16_t address) const noexcept { return (address - begin) & mask; } - Memory& memory; uint16_t begin = Chip::Mask16; uint16_t mask = 0U; AccessLevel access = AccessLevel::Unknown; + + MemoryMapping(Memory& memory, uint16_t begin, uint16_t mask, AccessLevel access) noexcept + : memory(memory), + begin(begin), + mask(mask), + access(access) { + for (int i = minimum; i < maximum + 1; ++i) { + assert(i >= minimum); + assert(i <= maximum); + _offsets[i] = create_offset(i); + } + } + + constexpr auto offset(uint16_t address) const noexcept { + return _offsets[address]; + } }; } diff --git a/src/Bus.cpp b/src/Bus.cpp index a0bc701..b647c9b 100644 --- a/src/Bus.cpp +++ b/src/Bus.cpp @@ -13,7 +13,11 @@ void EightBit::Bus::read() noexcept { } void EightBit::Bus::write() noexcept { + assert(!m_writing); + m_writing = true; reference() = DATA(); + m_writing = false; + assert(!m_writing); } void EightBit::Bus::loadHexFile(const std::string& path) { @@ -28,9 +32,11 @@ void EightBit::Bus::loadHexFile(const std::string& path) { } uint8_t& EightBit::Bus::reference(const uint16_t address) noexcept { - const auto mapped = mapping(address); + const auto& mapped = mapping(address); const auto offset = mapped.offset(address); if (mapped.access != MemoryMapping::AccessLevel::ReadOnly) return mapped.memory.reference(offset); - return DATA() = mapped.memory.peek(offset); + if (!m_writing) + DATA() = mapped.memory.peek(offset); + return DATA(); } diff --git a/unittest_EightBit/BusTests.cpp b/unittest_EightBit/BusTests.cpp new file mode 100644 index 0000000..f2ee5dc --- /dev/null +++ b/unittest_EightBit/BusTests.cpp @@ -0,0 +1,63 @@ +#include "pch.h" +#include +#include +#include + +// Minimal Bus whose entire address space maps to a single read-only RAM region. +// seed()/rawPeek() reach the RAM directly, bypassing the access-level check, +// so they can be used to set up and verify the underlying memory independently +// of whatever the Bus write path does. +namespace { + class ReadOnlyBus : public EightBit::Bus { + EightBit::Ram m_ram{ 0x10000 }; + EightBit::MemoryMapping m_mapping; + public: + ReadOnlyBus() + : m_mapping{ m_ram, 0x0000, EightBit::Chip::Mask16, + EightBit::MemoryMapping::AccessLevel::ReadOnly } {} + + /// Writes directly to the backing RAM, bypassing the access-level guard. + void seed(uint16_t address, uint8_t value) { m_ram.poke(address, value); } + + /// Reads directly from the backing RAM, bypassing the access-level guard. + uint8_t rawPeek(uint16_t address) const { return m_ram.peek(address); } + + const EightBit::MemoryMapping& mapping(uint16_t) noexcept final { return m_mapping; } + void initialise() noexcept final {} + }; +} + +BOOST_AUTO_TEST_SUITE(Bus) + +BOOST_AUTO_TEST_CASE(read_from_ReadOnly_returns_memory_value) { + ReadOnlyBus bus; + bus.seed(0x1000, 0xAB); + bus.ADDRESS() = 0x1000; + bus.read(); + BOOST_CHECK_EQUAL(bus.DATA(), 0xAB); +} + +BOOST_AUTO_TEST_CASE(write_to_ReadOnly_does_not_modify_memory) { + ReadOnlyBus bus; + bus.seed(0x2000, 0x55); + bus.ADDRESS() = 0x2000; + bus.DATA() = 0xFF; + bus.write(); + // Memory must be unchanged. + BOOST_CHECK_EQUAL(bus.rawPeek(0x2000), 0x55); + // Write to read-only mapping must leave the written value on the bus, not the memory value + BOOST_CHECK_EQUAL(bus.DATA(), 0xff); +} + +BOOST_AUTO_TEST_CASE(read_after_write_to_ReadOnly_returns_original_value) { + ReadOnlyBus bus; + bus.seed(0x3000, 0x42); + bus.ADDRESS() = 0x3000; + bus.DATA() = 0xFF; + bus.write(); // silently discarded — memory unchanged + bus.DATA() = 0x00; // clear DATA to prove the subsequent read loads from memory + bus.read(); + BOOST_CHECK_EQUAL(bus.DATA(), 0x42); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/unittest_EightBit/ChipTests.cpp b/unittest_EightBit/ChipTests.cpp new file mode 100644 index 0000000..e9c598f --- /dev/null +++ b/unittest_EightBit/ChipTests.cpp @@ -0,0 +1,81 @@ +#include "pch.h" +#include + +BOOST_AUTO_TEST_SUITE(Chip) + +BOOST_AUTO_TEST_CASE(bit_returns_correct_bit_mask) { + BOOST_CHECK_EQUAL(EightBit::Chip::bit(0), 0x01); + BOOST_CHECK_EQUAL(EightBit::Chip::bit(1), 0x02); + BOOST_CHECK_EQUAL(EightBit::Chip::bit(7), 0x80); + BOOST_CHECK_EQUAL(EightBit::Chip::bit(3), 0x08); +} + +BOOST_AUTO_TEST_CASE(setBit_sets_bits_correctly) { + BOOST_CHECK_EQUAL(EightBit::Chip::setBit((uint8_t)0b00001001, 0b00000100), 0b00001101); + BOOST_CHECK_EQUAL(EightBit::Chip::setBit((uint8_t)0b00001101, 0b00000100), 0b00001101); + BOOST_CHECK_EQUAL(EightBit::Chip::setBit((uint8_t)0b00001101, 0b00000100, true), 0b00001101); + BOOST_CHECK_EQUAL(EightBit::Chip::setBit((uint8_t)0b00001101, 0b00000100, false), 0b00001001); +} + +BOOST_AUTO_TEST_CASE(clearBit_clears_bits_correctly) { + BOOST_CHECK_EQUAL(EightBit::Chip::clearBit((uint8_t)0b00001101, 0b00000100), 0b00001001); + BOOST_CHECK_EQUAL(EightBit::Chip::clearBit((uint8_t)0b00001101, 0b00000100, false), 0b00001101); + BOOST_CHECK_EQUAL(EightBit::Chip::clearBit((uint8_t)0b00001101, 0b00000100, true), 0b00001001); +} + +BOOST_AUTO_TEST_CASE(highByte_and_lowByte_work_correctly) { + const uint16_t u16 = 0xABCD; + BOOST_CHECK_EQUAL(EightBit::Chip::highByte(u16), 0xAB); + BOOST_CHECK_EQUAL(EightBit::Chip::lowByte(u16), 0xCD); + + const int i32 = 0x1234; + BOOST_CHECK_EQUAL(EightBit::Chip::highByte(i32), 0x12); + BOOST_CHECK_EQUAL(EightBit::Chip::lowByte(i32), 0x34); +} + +BOOST_AUTO_TEST_CASE(promoteByte_and_demoteByte_work_correctly) { + BOOST_CHECK_EQUAL(EightBit::Chip::promoteByte((uint8_t)0x34), 0x3400); + BOOST_CHECK_EQUAL(EightBit::Chip::demoteByte((uint16_t)0x1234), 0x12); +} + +BOOST_AUTO_TEST_CASE(higherPart_and_lowerPart_work_correctly) { + const uint16_t value = 0xABCD; + BOOST_CHECK_EQUAL(EightBit::Chip::higherPart(value), 0xAB00); + BOOST_CHECK_EQUAL(EightBit::Chip::lowerPart(value), 0xCD); +} + +BOOST_AUTO_TEST_CASE(makeWord_creates_correct_word) { + BOOST_CHECK_EQUAL(EightBit::Chip::makeWord((uint8_t)0x34, (uint8_t)0x12), 0x1234); +} + +BOOST_AUTO_TEST_CASE(nibble_methods_work_correctly) { + const uint8_t value = 0xAB; + BOOST_CHECK_EQUAL(EightBit::Chip::highNibble(value), 0x0A); + BOOST_CHECK_EQUAL(EightBit::Chip::lowNibble(value), 0x0B); + BOOST_CHECK_EQUAL(EightBit::Chip::higherNibble(value), 0xA0); + BOOST_CHECK_EQUAL(EightBit::Chip::lowerNibble(value), 0x0B); + BOOST_CHECK_EQUAL(EightBit::Chip::promoteNibble(value), 0xB0); + BOOST_CHECK_EQUAL(EightBit::Chip::demoteNibble(value), 0x0A); +} + +BOOST_AUTO_TEST_CASE(countBits_returns_correct_count) { + BOOST_CHECK_EQUAL(EightBit::Chip::countBits(0U), 0); + BOOST_CHECK_EQUAL(EightBit::Chip::countBits(1U), 1); + BOOST_CHECK_EQUAL(EightBit::Chip::countBits(0xFFU), 8); +} + +BOOST_AUTO_TEST_CASE(evenParity_returns_correct_parity) { + BOOST_CHECK( EightBit::Chip::evenParity(0U)); // 0 bits set — even + BOOST_CHECK(!EightBit::Chip::evenParity(1U)); // 1 bit set — odd + BOOST_CHECK( EightBit::Chip::evenParity(3U)); // 2 bits set — even +} + +BOOST_AUTO_TEST_CASE(findFirstSet_returns_correct_index) { + BOOST_CHECK_EQUAL(EightBit::Chip::findFirstSet(0UL), 0); + BOOST_CHECK_EQUAL(EightBit::Chip::findFirstSet(1UL), 1); + BOOST_CHECK_EQUAL(EightBit::Chip::findFirstSet(2UL), 2); + BOOST_CHECK_EQUAL(EightBit::Chip::findFirstSet(4UL), 3); + BOOST_CHECK_EQUAL(EightBit::Chip::findFirstSet(0b10000UL), 5); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/unittest_EightBit/DeviceTests.cpp b/unittest_EightBit/DeviceTests.cpp new file mode 100644 index 0000000..e28642f --- /dev/null +++ b/unittest_EightBit/DeviceTests.cpp @@ -0,0 +1,80 @@ +#include "pch.h" +#include + +// Device has a protected constructor, so we expose it via a minimal subclass. +namespace { + class TestDevice : public EightBit::Device { + public: + TestDevice() = default; + }; +} + +BOOST_AUTO_TEST_SUITE(Device) + +BOOST_AUTO_TEST_CASE(initial_state_is_not_powered) { + TestDevice device; + BOOST_CHECK(!device.powered()); + BOOST_CHECK(device.POWER() == EightBit::Device::PinLevel::Low); +} + +BOOST_AUTO_TEST_CASE(raisePOWER_sets_POWER_high_and_fires_events) { + TestDevice device; + bool raising = false, raised = false; + + device.RaisingPOWER.connect([&raising](EightBit::EventArgs&) { raising = true; }); + device.RaisedPOWER.connect([&raised](EightBit::EventArgs&) { raised = true; }); + + device.raisePOWER(); + + BOOST_CHECK(device.powered()); + BOOST_CHECK(device.POWER() == EightBit::Device::PinLevel::High); + BOOST_CHECK(raising); + BOOST_CHECK(raised); +} + +BOOST_AUTO_TEST_CASE(lowerPOWER_sets_POWER_low_and_fires_events) { + TestDevice device; + device.raisePOWER(); // start high + + bool lowering = false, lowered = false; + device.LoweringPOWER.connect([&lowering](EightBit::EventArgs&) { lowering = true; }); + device.LoweredPOWER.connect([&lowered](EightBit::EventArgs&) { lowered = true; }); + + device.lowerPOWER(); + + BOOST_CHECK(!device.powered()); + BOOST_CHECK(device.POWER() == EightBit::Device::PinLevel::Low); + BOOST_CHECK(lowering); + BOOST_CHECK(lowered); +} + +BOOST_AUTO_TEST_CASE(raisePOWER_does_nothing_if_already_high) { + TestDevice device; + device.raisePOWER(); + + bool raising = false, raised = false; + device.RaisingPOWER.connect([&raising](EightBit::EventArgs&) { raising = true; }); + device.RaisedPOWER.connect([&raised](EightBit::EventArgs&) { raised = true; }); + + device.raisePOWER(); // already high — should be a no-op + + BOOST_CHECK(device.powered()); + BOOST_CHECK(!raising); + BOOST_CHECK(!raised); +} + +BOOST_AUTO_TEST_CASE(lowerPOWER_does_nothing_if_already_low) { + TestDevice device; // starts low + + bool lowering = false, lowered = false; + device.LoweringPOWER.connect([&lowering](EightBit::EventArgs&) { lowering = true; }); + device.LoweredPOWER.connect([&lowered](EightBit::EventArgs&) { lowered = true; }); + + device.lowerPOWER(); // already low — should be a no-op + + BOOST_CHECK(!device.powered()); + BOOST_CHECK(!lowering); + BOOST_CHECK(!lowered); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/unittest_EightBit/pch.cpp b/unittest_EightBit/pch.cpp new file mode 100644 index 0000000..3a3d12b --- /dev/null +++ b/unittest_EightBit/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed + +#include "pch.h" + +// In general, ignore this file, but keep it around if you are using pre-compiled headers. diff --git a/unittest_EightBit/pch.h b/unittest_EightBit/pch.h new file mode 100644 index 0000000..feda3d1 --- /dev/null +++ b/unittest_EightBit/pch.h @@ -0,0 +1,5 @@ +#ifdef _MSC_VER +#pragma once +#endif + +#include diff --git a/unittest_EightBit/unittest_EightBit.cpp b/unittest_EightBit/unittest_EightBit.cpp new file mode 100644 index 0000000..a6d2750 --- /dev/null +++ b/unittest_EightBit/unittest_EightBit.cpp @@ -0,0 +1,2 @@ +#define BOOST_TEST_MODULE EightBitUnitTests +#include diff --git a/unittest_EightBit/unittest_EightBit.vcxproj b/unittest_EightBit/unittest_EightBit.vcxproj new file mode 100644 index 0000000..4a0c278 --- /dev/null +++ b/unittest_EightBit/unittest_EightBit.vcxproj @@ -0,0 +1,205 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {7D2F4A8C-1B35-4E96-A0D7-3F8C2B6E1A5D} + Win32Proj + unittestEightBit + 10.0 + + + + Application + true + v145 + Unicode + + + v145 + true + + + Application + true + v145 + Unicode + + + v145 + true + + + + + + + + + + + + + + + + + + + + + false + ..\inc;C:\Libraries\boost_1_88_0;$(IncludePath) + + + true + ..\inc;C:\Libraries\boost_1_88_0;$(IncludePath) + + + true + ..\inc;C:\Libraries\boost_1_88_0;$(IncludePath) + + + false + ..\inc;C:\Libraries\boost_1_88_0;$(IncludePath) + + + + Use + Level3 + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + pch.h + stdcpp20 + /Zc:__cplusplus %(AdditionalOptions) + Speed + false + AdvancedVectorExtensions + Fast + + + true + true + + + $(TargetPath) + + + Running tests + + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + pch.h + stdcpp20 + /Zc:__cplusplus %(AdditionalOptions) + + + Console + true + + + + + + + Running tests + + + + + Use + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + pch.h + stdcpp20 + /Zc:__cplusplus %(AdditionalOptions) + + + Console + true + + + + + + + Running tests + + + + + Use + Level3 + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + pch.h + stdcpp20 + /Zc:__cplusplus %(AdditionalOptions) + Speed + false + AdvancedVectorExtensions + Fast + + + true + true + + + $(TargetPath) + + + Running tests + + + + + + + + + + + Create + Create + Create + Create + + + NotUsing + NotUsing + NotUsing + NotUsing + + + + + {a9c24bd9-0cb4-4c84-b09b-46b815f9da47} + + + + + +