Last active
July 27, 2018 10:44
-
-
Save Bktero/5d4b3ef4d020e47e8aabfb7b7aad1429 to your computer and use it in GitHub Desktop.
[C++17] Example of std::variant to execute various type of request on a SPI bus
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <cassert> | |
| #include <cstdint> | |
| #include <variant> | |
| struct ReadRequest { | |
| ReadRequest(std::uint8_t* data, std::size_t length) : | |
| data(data), | |
| length(length) { | |
| assert(data != nullptr); | |
| } | |
| std::uint8_t* const data; | |
| const std::size_t length; | |
| }; | |
| struct WriteRequest { | |
| WriteRequest(const std::uint8_t* data, std::size_t length) : | |
| data(data), | |
| length(length) { | |
| assert(data != nullptr); | |
| } | |
| const std::uint8_t* const data; | |
| const std::size_t length; | |
| }; | |
| struct WriteReadRequest { | |
| WriteReadRequest(const std::uint8_t* writeData, std::size_t writeLength, | |
| std::uint8_t* readData, std::size_t readLength) : | |
| readData(readData), | |
| readLength(readLength), | |
| writeData(writeData), | |
| writeLength(writeLength) { | |
| assert(readData != nullptr); | |
| assert(writeData != nullptr); | |
| } | |
| std::uint8_t* const readData; | |
| const std::size_t readLength; | |
| const std::uint8_t* const writeData; | |
| const std::size_t writeLength; | |
| }; | |
| struct DoubleWriteRequest { | |
| DoubleWriteRequest(const std::uint8_t* firstData, std::size_t firstLength, | |
| const std::uint8_t* secondData, std::size_t secondLength) : | |
| firstData(firstData), | |
| firstLength(firstLength), | |
| secondData(secondData), | |
| secondLength(secondLength) { | |
| assert(firstData != nullptr); | |
| assert(secondData != nullptr); | |
| } | |
| const std::uint8_t* const firstData; | |
| const std::size_t firstLength; | |
| const std::uint8_t* const secondData; | |
| const std::size_t secondLength; | |
| }; | |
| using Request =std::variant<ReadRequest, | |
| WriteRequest, | |
| WriteReadRequest, | |
| DoubleWriteRequest>; | |
| //--------------------------------------------------------------------------------- | |
| extern "C" { | |
| void spi_driver_read(std::uint8_t* data, std::size_t length); | |
| void spi_driver_write(const std::uint8_t* data, std::size_t length); | |
| } | |
| class SpiBus { | |
| public: | |
| void execute(const Request& request) { | |
| RequestProcessor requestProcessor; | |
| std::visit(requestProcessor, request); | |
| } | |
| private: | |
| class RequestProcessor { | |
| public: | |
| void operator()(const ReadRequest& request) { | |
| spi_driver_read(request.data, request.length); | |
| } | |
| void operator()(const WriteRequest& request) { | |
| spi_driver_write(request.data, request.length); | |
| } | |
| void operator()(const WriteReadRequest& request) { | |
| spi_driver_write(request.writeData, request.writeLength); | |
| spi_driver_read(request.readData, request.readLength); | |
| } | |
| void operator()(const DoubleWriteRequest& request) { | |
| spi_driver_write(request.firstData, request.firstLength); | |
| spi_driver_write(request.secondData, request.secondLength); | |
| } | |
| }; | |
| }; | |
| //-------------------------------------------------------------------------------- | |
| #include <array> | |
| int main() { | |
| SpiBus bus; | |
| std::array<std::uint8_t, 15> buffer; | |
| ReadRequest rr{buffer.data(), buffer.size()}; | |
| bus.execute(rr); | |
| //ReadRequest bad_rr{nullptr, 42}; // triggers assert() | |
| WriteRequest wr{buffer.data(), buffer.size()}; | |
| bus.execute(wr); | |
| WriteReadRequest wrr{buffer.data(), 2, buffer.data(), 13}; | |
| bus.execute(wrr); | |
| DoubleWriteRequest dwr{buffer.data(), 10, buffer.data(), 5}; | |
| bus.execute(dwr); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment