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 | 4 | include(projectheader) |
5 | 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 | 8 | add_subdirectory(src) |
9 | 9 | |
10 | 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 | 2 | |
3 | 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 | 139 | \ No newline at end of file | ... | ... |
src/Variant.h
1 | -#pragma one | |
1 | +#pragma once | |
2 | 2 | |
3 | +#include <cstdint> | |
3 | 4 | #include <string> |
5 | +#include <variant> | |
6 | + | |
4 | 7 | namespace osdev::components { |
8 | + | |
5 | 9 | class Variant |
6 | 10 | { |
7 | 11 | public: |
8 | 12 | enum Type { |
9 | 13 | Invalid, // Unknown |
10 | 14 | Bool, // bool |
11 | - Int, // int (standard) | |
12 | - UInt, // Unsigned int | |
13 | 15 | Double, // double |
14 | 16 | Float, // float |
15 | 17 | Char, // char |
16 | 18 | String, // std::string |
17 | 19 | UInt8, // uint8_t |
18 | 20 | UInt16, // uint16_t |
19 | - UInt32, // uint32_t | |
20 | 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 | 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 | + | ... | ... |