Commit a6b8531dcb7aa8d39a69f5cb72d6cdfe2a8e8cf3
1 parent
c96f4e8b
Implemented the Variant and tests
Showing
6 changed files
with
330 additions
and
71 deletions
.gitignore
CMakeLists.txt
| @@ -4,10 +4,10 @@ LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake) | @@ -4,10 +4,10 @@ LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake) | ||
| 4 | include(projectheader) | 4 | include(projectheader) |
| 5 | project_header(datatypes) | 5 | project_header(datatypes) |
| 6 | 6 | ||
| 7 | -# set(REPOSITORY_PACKAGE_NAME ${PROJECT_NAME} CACHE STRING "Repository name for ${PROJECT_NAME}" FORCE) | 7 | +set(REPOSITORY_PACKAGE_NAME ${PROJECT_NAME} CACHE STRING "Repository name for ${PROJECT_NAME}" FORCE) |
| 8 | add_subdirectory(src) | 8 | add_subdirectory(src) |
| 9 | 9 | ||
| 10 | # Test applications for each component. | 10 | # Test applications for each component. |
| 11 | -# add_subdirectory(tests) | 11 | +add_subdirectory(tests) |
| 12 | 12 | ||
| 13 | 13 |
src/Variant.cpp
| @@ -2,75 +2,137 @@ | @@ -2,75 +2,137 @@ | ||
| 2 | 2 | ||
| 3 | using namespace osdev::components; | 3 | using namespace osdev::components; |
| 4 | 4 | ||
| 5 | -Variant::Variant() | ||
| 6 | -{ | ||
| 7 | -} | ||
| 8 | - | ||
| 9 | -Variant::Variant(Type type) | ||
| 10 | -{ | ||
| 11 | -} | ||
| 12 | - | ||
| 13 | -Variant::Variant(bool value) | ||
| 14 | -{ | ||
| 15 | -} | ||
| 16 | - | ||
| 17 | -Variant::Variant(int value) | ||
| 18 | -{ | ||
| 19 | -} | ||
| 20 | - | ||
| 21 | -Variant::Variant(uint value) | ||
| 22 | -{ | ||
| 23 | -} | ||
| 24 | - | ||
| 25 | -Variant::Variant(double value) | ||
| 26 | -{ | ||
| 27 | -} | 5 | +Variant::Type Variant::getType() |
| 6 | +{ | ||
| 7 | + if(std::holds_alternative<bool>(m_variable)) | ||
| 8 | + { | ||
| 9 | + return Variant::Type::Bool; | ||
| 10 | + } | ||
| 11 | + else if(std::holds_alternative<int>(m_variable)) | ||
| 12 | + { | ||
| 13 | + return Variant::Type::Int; | ||
| 14 | + } | ||
| 15 | + else if(std::holds_alternative<double>(m_variable)) | ||
| 16 | + { | ||
| 17 | + return Variant::Type::Double; | ||
| 18 | + } | ||
| 19 | + else if(std::holds_alternative<float>(m_variable)) | ||
| 20 | + { | ||
| 21 | + return Variant::Type::Float; | ||
| 22 | + } | ||
| 23 | + else if(std::holds_alternative<char>(m_variable)) | ||
| 24 | + { | ||
| 25 | + return Variant::Type::Char; | ||
| 26 | + } | ||
| 27 | + else if(std::holds_alternative<std::string>(m_variable)) | ||
| 28 | + { | ||
| 29 | + return Variant::Type::String; | ||
| 30 | + } | ||
| 31 | + else if(std::holds_alternative<uint8_t>(m_variable)) | ||
| 32 | + { | ||
| 33 | + return Variant::Type::UInt8; | ||
| 34 | + } | ||
| 35 | + else if(std::holds_alternative<uint16_t>(m_variable)) | ||
| 36 | + { | ||
| 37 | + return Variant::Type::UInt16; | ||
| 38 | + } | ||
| 39 | + else if(std::holds_alternative<uint64_t>(m_variable)) | ||
| 40 | + { | ||
| 41 | + return Variant::Type::UInt64; | ||
| 42 | + } | ||
| 28 | 43 | ||
| 29 | -Variant::Variant(float value) | ||
| 30 | -{ | 44 | + return Variant::Type::Invalid; |
| 31 | } | 45 | } |
| 32 | 46 | ||
| 33 | -Variant::Variant(char value) | 47 | +bool Variant::CanConvert(Variant::Type typeWanted) |
| 34 | { | 48 | { |
| 49 | + switch(typeWanted) | ||
| 50 | + { | ||
| 51 | + case Variant::Bool: | ||
| 52 | + { | ||
| 53 | + return std::holds_alternative<bool>(m_variable); | ||
| 54 | + } | ||
| 55 | + case Variant::Int: | ||
| 56 | + { | ||
| 57 | + return std::holds_alternative<int>(m_variable); | ||
| 58 | + } | ||
| 59 | + case Variant::Double: | ||
| 60 | + { | ||
| 61 | + return std::holds_alternative<double>(m_variable); | ||
| 62 | + } | ||
| 63 | + case Variant::Float: | ||
| 64 | + { | ||
| 65 | + return std::holds_alternative<float>(m_variable); | ||
| 66 | + } | ||
| 67 | + case Variant::Char: | ||
| 68 | + { | ||
| 69 | + return std::holds_alternative<char>(m_variable); | ||
| 70 | + } | ||
| 71 | + case Variant::String: | ||
| 72 | + { | ||
| 73 | + return std::holds_alternative<std::string>(m_variable); | ||
| 74 | + } | ||
| 75 | + case Variant::UInt8: | ||
| 76 | + { | ||
| 77 | + return std::holds_alternative<uint8_t>(m_variable); | ||
| 78 | + } | ||
| 79 | + case Variant::UInt16: | ||
| 80 | + { | ||
| 81 | + return std::holds_alternative<uint16_t>(m_variable); | ||
| 82 | + } | ||
| 83 | + case Variant::UInt64: | ||
| 84 | + { | ||
| 85 | + return std::holds_alternative<uint64_t>(m_variable); | ||
| 86 | + } | ||
| 87 | + case Variant::Invalid: | ||
| 88 | + { | ||
| 89 | + return false; | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + return false; | ||
| 35 | } | 93 | } |
| 36 | 94 | ||
| 37 | -Variant::Variant(std::string value) | 95 | +bool Variant::toBool() |
| 38 | { | 96 | { |
| 97 | + return std::get<bool>(m_variable); | ||
| 39 | } | 98 | } |
| 40 | 99 | ||
| 41 | -Variant::Variant(uint8_t value) | 100 | +int Variant::toInt() |
| 42 | { | 101 | { |
| 102 | + return std::get<int>(m_variable); | ||
| 43 | } | 103 | } |
| 44 | 104 | ||
| 45 | -Variant::Variant(uint16_t value) | 105 | +double Variant::toDouble() |
| 46 | { | 106 | { |
| 107 | + return std::get<double>(m_variable); | ||
| 47 | } | 108 | } |
| 48 | 109 | ||
| 49 | -Variant::Variant(uint32_t value) | 110 | +float Variant::toFloat() |
| 50 | { | 111 | { |
| 112 | + return std::get<float>(m_variable); | ||
| 51 | } | 113 | } |
| 52 | 114 | ||
| 53 | -Variant::Variant(uint64_t value) | 115 | +char Variant::toChar() |
| 54 | { | 116 | { |
| 117 | + return std::get<char>(m_variable); | ||
| 55 | } | 118 | } |
| 56 | 119 | ||
| 57 | -Variant::Variant(int8_t value) | 120 | +std::string Variant::toString() |
| 58 | { | 121 | { |
| 122 | + return std::get<std::string>(m_variable); | ||
| 59 | } | 123 | } |
| 60 | 124 | ||
| 61 | -Variant::Variant(int16_t value) | 125 | +uint8_t Variant::toUInt8() |
| 62 | { | 126 | { |
| 127 | + return std::get<uint8_t>(m_variable); | ||
| 63 | } | 128 | } |
| 64 | 129 | ||
| 65 | -Variant::Variant(int32_t value) | 130 | +uint16_t Variant::toUInt16() |
| 66 | { | 131 | { |
| 132 | + return std::get<uint16_t>(m_variable); | ||
| 67 | } | 133 | } |
| 68 | 134 | ||
| 69 | -Variant::Variant(int64_t value) | 135 | +uint64_t Variant::toUInt64() |
| 70 | { | 136 | { |
| 137 | + return std::get<uint64_t>(m_variable); | ||
| 71 | } | 138 | } |
| 72 | - | ||
| 73 | -Type Variant::getType() | ||
| 74 | -{ | ||
| 75 | - | ||
| 76 | -} | ||
| 77 | \ No newline at end of file | 139 | \ No newline at end of file |
src/Variant.h
| 1 | -#pragma one | 1 | +#pragma once |
| 2 | 2 | ||
| 3 | +#include <cstdint> | ||
| 3 | #include <string> | 4 | #include <string> |
| 5 | +#include <variant> | ||
| 6 | + | ||
| 4 | namespace osdev::components { | 7 | namespace osdev::components { |
| 8 | + | ||
| 5 | class Variant | 9 | class Variant |
| 6 | { | 10 | { |
| 7 | public: | 11 | public: |
| 8 | enum Type { | 12 | enum Type { |
| 9 | Invalid, // Unknown | 13 | Invalid, // Unknown |
| 10 | Bool, // bool | 14 | Bool, // bool |
| 11 | - Int, // int (standard) | ||
| 12 | - UInt, // Unsigned int | ||
| 13 | Double, // double | 15 | Double, // double |
| 14 | Float, // float | 16 | Float, // float |
| 15 | Char, // char | 17 | Char, // char |
| 16 | String, // std::string | 18 | String, // std::string |
| 17 | UInt8, // uint8_t | 19 | UInt8, // uint8_t |
| 18 | UInt16, // uint16_t | 20 | UInt16, // uint16_t |
| 19 | - UInt32, // uint32_t | ||
| 20 | UInt64, // uint64_t | 21 | UInt64, // uint64_t |
| 21 | - Int8, // int8_t | ||
| 22 | - Int16, // int16_t | ||
| 23 | - Int32, // int32_t | ||
| 24 | - Int64 // int64_t | 22 | + Int // int -->> Size determined by platform and compiler |
| 25 | }; | 23 | }; |
| 26 | 24 | ||
| 27 | /*! | 25 | /*! |
| 28 | - * All Constructors available | 26 | + * All Constructors available. |
| 27 | + * The type of the argument determines the internal type of the variant | ||
| 29 | */ | 28 | */ |
| 30 | - Variant(); | ||
| 31 | - Variant(Type type); | ||
| 32 | - Variant(bool value); | ||
| 33 | - Variant(int value); | ||
| 34 | - Variant(uint value); | ||
| 35 | - Variant(double value); | ||
| 36 | - Variant(float value); | ||
| 37 | - Variant(char value); | ||
| 38 | - Variant(std::string value); | ||
| 39 | - Variant(uint8_t value); | ||
| 40 | - Variant(uint16_t value); | ||
| 41 | - Variant(uint32_t value); | ||
| 42 | - Variant(uint64_t value); | ||
| 43 | - Variant(int8_t value); | ||
| 44 | - Variant(int16_t value); | ||
| 45 | - Variant(int32_t value); | ||
| 46 | - Variant(int64_t value); | ||
| 47 | - | ||
| 48 | - | 29 | + Variant() : m_variable() {}; |
| 30 | + Variant(bool value) : m_variable(value) {}; | ||
| 31 | + Variant(int value) : m_variable(value) {}; | ||
| 32 | + Variant(double value) : m_variable(value) {}; | ||
| 33 | + Variant(float value) : m_variable(value) {}; | ||
| 34 | + Variant(char value) : m_variable(value) {}; | ||
| 35 | + Variant(std::string value) : m_variable(value) {}; | ||
| 36 | + Variant(uint8_t value) : m_variable(value) {}; | ||
| 37 | + Variant(uint16_t value) : m_variable(value) {}; | ||
| 38 | + Variant(uint64_t value) : m_variable(value) {}; | ||
| 39 | + | ||
| 40 | + /// Return the type of the value stored in this variant | ||
| 41 | + Variant::Type getType(); | ||
| 42 | + | ||
| 43 | + /// Check to see if the value can be converted to the desired type. | ||
| 44 | + /// @param - The requested type as an enum | ||
| 45 | + /// @return - true if the conversion can happen. False if not. | ||
| 46 | + bool CanConvert(Variant::Type typeWanted); | ||
| 47 | + | ||
| 48 | + bool toBool(); | ||
| 49 | + double toDouble(); | ||
| 50 | + float toFloat(); | ||
| 51 | + char toChar(); | ||
| 52 | + std::string toString(); | ||
| 53 | + int toInt(); | ||
| 54 | + uint8_t toUInt8(); | ||
| 55 | + uint16_t toUInt16(); | ||
| 56 | + uint64_t toUInt64(); | ||
| 57 | + | ||
| 58 | + | ||
| 59 | + | ||
| 60 | +private: | ||
| 61 | + std::variant<bool, int, | ||
| 62 | + double, float, | ||
| 63 | + char, std::string, | ||
| 64 | + uint8_t, uint16_t, | ||
| 65 | + uint64_t> m_variable; | ||
| 66 | + | ||
| 49 | }; | 67 | }; |
| 50 | 68 | ||
| 51 | -} /* End namespace osdev::components */ | ||
| 52 | \ No newline at end of file | 69 | \ No newline at end of file |
| 70 | +} /* End namespace osdev::components */ |
tests/CMakeLists.txt
0 โ 100644
| 1 | +# ***************************************************************************** | ||
| 2 | +# Copyright (c)2023 Peter M. Groen | ||
| 3 | +# This file is licensed under the MIT license found in the LICENSE file | ||
| 4 | +# in the root directory of this source tree. | ||
| 5 | +# ***************************************************************************** | ||
| 6 | +add_executable(datatypestest | ||
| 7 | + datatypestest.cpp | ||
| 8 | +) | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +target_include_directories(datatypestest PRIVATE | ||
| 12 | + ${CMAKE_CURRENT_SOURCE_DIR} | ||
| 13 | + ${CMAKE_SOURCE_DIR}/src | ||
| 14 | + ${CMAKE_BINARY_DIR} | ||
| 15 | +) | ||
| 16 | + | ||
| 17 | +target_link_libraries(datatypestest PRIVATE | ||
| 18 | + gmock_main | ||
| 19 | + gmock | ||
| 20 | + gtest | ||
| 21 | + datatypes | ||
| 22 | +) | ||
| 23 | + | ||
| 24 | +add_test(NAME datatypestest COMMAND datatypestest) | ||
| 25 | + | ||
| 26 | +set_tests_properties(datatypestest PROPERTIES | ||
| 27 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" | ||
| 28 | +) |
tests/datatypestest.cpp
0 โ 100644
| 1 | +/***************************************************************************** | ||
| 2 | + * Copyright (c)2023 Peter M. Groen | ||
| 3 | + * This file is licensed under the MIT license found in the LICENSE file | ||
| 4 | + * in the root directory of this source tree. | ||
| 5 | + ******************************************************************************/ | ||
| 6 | + | ||
| 7 | +#include <gmock/gmock.h> | ||
| 8 | +#include <gtest/gtest.h> | ||
| 9 | + | ||
| 10 | +#include "Variant.h" | ||
| 11 | + | ||
| 12 | +using namespace osdev::components; | ||
| 13 | + | ||
| 14 | +TEST(DataTypesTest, BooleanTest) | ||
| 15 | +{ | ||
| 16 | + Variant oVariant(true); | ||
| 17 | + EXPECT_EQ(oVariant.getType(), Variant::Bool); | ||
| 18 | + EXPECT_TRUE(oVariant.CanConvert(Variant::Bool)); | ||
| 19 | + EXPECT_TRUE(oVariant.toBool()); | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +TEST(DataTypesTest, PositiveIntegerTest) | ||
| 23 | +{ | ||
| 24 | + int value = 42; | ||
| 25 | + Variant oVariant(value); | ||
| 26 | + EXPECT_EQ(oVariant.getType(), Variant::Int); | ||
| 27 | + EXPECT_TRUE(oVariant.CanConvert(Variant::Int)); | ||
| 28 | + EXPECT_EQ(oVariant.toInt(), 42); | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +TEST(DataTypesTest, NegativeIntegerTest) | ||
| 32 | +{ | ||
| 33 | + int value = -42; | ||
| 34 | + Variant oVariant(value); | ||
| 35 | + EXPECT_EQ(oVariant.getType(), Variant::Int); | ||
| 36 | + EXPECT_TRUE(oVariant.CanConvert(Variant::Int)); | ||
| 37 | + EXPECT_EQ(oVariant.toInt(), -42); | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +TEST(DataTypesTest, PositiveDoubleTest) | ||
| 41 | +{ | ||
| 42 | + double value = 42; | ||
| 43 | + Variant oVariant(value); | ||
| 44 | + EXPECT_EQ(oVariant.getType(), Variant::Double); | ||
| 45 | + EXPECT_TRUE(oVariant.CanConvert(Variant::Double)); | ||
| 46 | + EXPECT_EQ(oVariant.toDouble(), 42); | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +TEST(DataTypesTest, NegativeDoubleTest) | ||
| 50 | +{ | ||
| 51 | + double value = -42; | ||
| 52 | + Variant oVariant(value); | ||
| 53 | + EXPECT_EQ(oVariant.getType(), Variant::Double); | ||
| 54 | + EXPECT_TRUE(oVariant.CanConvert(Variant::Double)); | ||
| 55 | + EXPECT_EQ(oVariant.toDouble(), -42); | ||
| 56 | +} | ||
| 57 | + | ||
| 58 | +TEST(DataTypesTest, PositiveFloatTest) | ||
| 59 | +{ | ||
| 60 | + float value = 42.00; | ||
| 61 | + Variant oVariant(value); | ||
| 62 | + EXPECT_EQ(oVariant.getType(), Variant::Float); | ||
| 63 | + EXPECT_TRUE(oVariant.CanConvert(Variant::Float)); | ||
| 64 | + EXPECT_EQ(oVariant.toFloat(), 42.00); | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +TEST(DataTypesTest, NegativeFloatTest) | ||
| 68 | +{ | ||
| 69 | + float value = -42.00; | ||
| 70 | + Variant oVariant(value); | ||
| 71 | + EXPECT_EQ(oVariant.getType(), Variant::Float); | ||
| 72 | + EXPECT_TRUE(oVariant.CanConvert(Variant::Float)); | ||
| 73 | + EXPECT_EQ(oVariant.toFloat(), -42.00); | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +TEST(DataTypesTest, CharTest) | ||
| 77 | +{ | ||
| 78 | + char value = 'c'; | ||
| 79 | + Variant oVariant(value); | ||
| 80 | + EXPECT_EQ(oVariant.getType(), Variant::Char); | ||
| 81 | + EXPECT_TRUE(oVariant.CanConvert(Variant::Char)); | ||
| 82 | + EXPECT_EQ(oVariant.toChar(), 'c'); | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +TEST(DataTypesTest, StringTest) | ||
| 86 | +{ | ||
| 87 | + std::string value = "This is a string"; | ||
| 88 | + Variant oVariant(value); | ||
| 89 | + EXPECT_EQ(oVariant.getType(), Variant::String); | ||
| 90 | + EXPECT_TRUE(oVariant.CanConvert(Variant::String)); | ||
| 91 | + EXPECT_EQ(oVariant.toString(), "This is a string"); | ||
| 92 | +} | ||
| 93 | + | ||
| 94 | +TEST(DataTypesTest, UInt8Test) | ||
| 95 | +{ | ||
| 96 | + uint8_t value = 0xAA; | ||
| 97 | + Variant oVariant(value); | ||
| 98 | + EXPECT_EQ(oVariant.getType(), Variant::UInt8); | ||
| 99 | + EXPECT_TRUE(oVariant.CanConvert(Variant::UInt8)); | ||
| 100 | + EXPECT_EQ(oVariant.toUInt8(), 0xAA); | ||
| 101 | +} | ||
| 102 | + | ||
| 103 | +TEST(DataTypesTest, UInt16Test) | ||
| 104 | +{ | ||
| 105 | + uint16_t value = 0xAAAA; | ||
| 106 | + Variant oVariant(value); | ||
| 107 | + EXPECT_EQ(oVariant.getType(), Variant::UInt16); | ||
| 108 | + EXPECT_TRUE(oVariant.CanConvert(Variant::UInt16)); | ||
| 109 | + EXPECT_EQ(oVariant.toUInt16(), 0xAAAA); | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +TEST(DataTypesTest, UInt64Test) | ||
| 113 | +{ | ||
| 114 | + uint64_t value = 0xAAAAAAAAAAAAAAAA; | ||
| 115 | + Variant oVariant(value); | ||
| 116 | + EXPECT_EQ(oVariant.getType(), Variant::UInt64); | ||
| 117 | + EXPECT_TRUE(oVariant.CanConvert(Variant::UInt64)); | ||
| 118 | + EXPECT_EQ(oVariant.toUInt64(), 0xAAAAAAAAAAAAAAAA); | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +TEST(DataTypesTest, CanConvertTest) | ||
| 122 | +{ | ||
| 123 | + uint64_t value = 0xAAAAAAAAAAAAAAAA; | ||
| 124 | + Variant oVariant(value); | ||
| 125 | + EXPECT_FALSE(oVariant.CanConvert(Variant::Bool)); | ||
| 126 | + EXPECT_FALSE(oVariant.CanConvert(Variant::Int)); | ||
| 127 | + EXPECT_FALSE(oVariant.CanConvert(Variant::Double)); | ||
| 128 | + EXPECT_FALSE(oVariant.CanConvert(Variant::Float)); | ||
| 129 | + EXPECT_FALSE(oVariant.CanConvert(Variant::Char)); | ||
| 130 | + EXPECT_FALSE(oVariant.CanConvert(Variant::String)); | ||
| 131 | + EXPECT_FALSE(oVariant.CanConvert(Variant::UInt8)); | ||
| 132 | + EXPECT_FALSE(oVariant.CanConvert(Variant::UInt16)); | ||
| 133 | + EXPECT_TRUE(oVariant.CanConvert(Variant::UInt64)); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +TEST(DataTypesTest, GetWrongTypeTest) | ||
| 137 | +{ | ||
| 138 | + uint64_t value = 0xAAAAAAAAAAAAAAAA; | ||
| 139 | + Variant oVariant(value); | ||
| 140 | + EXPECT_ANY_THROW(oVariant.toBool()); | ||
| 141 | + EXPECT_ANY_THROW(oVariant.toInt()); | ||
| 142 | + EXPECT_ANY_THROW(oVariant.toDouble()); | ||
| 143 | + EXPECT_ANY_THROW(oVariant.toFloat()); | ||
| 144 | + EXPECT_ANY_THROW(oVariant.toChar()); | ||
| 145 | + EXPECT_ANY_THROW(oVariant.toString()); | ||
| 146 | + EXPECT_ANY_THROW(oVariant.toUInt8()); | ||
| 147 | + EXPECT_ANY_THROW(oVariant.toUInt16()); | ||
| 148 | + EXPECT_NO_THROW(oVariant.toUInt64()); | ||
| 149 | +} | ||
| 150 | + |