Skip to content

Commit da00e91

Browse files
committed
Move to C++17 from C++14
* Use std::string_view where appropriate * Utilize move to string_view to make tokenizer constexpr * Use std::gcd to simplify RationalNumbers as they are computed * Enable fuzz testing * Fix empty string parsing bug * Utilize [[nodiscard]] and [[maybe_unused]] TODO: * Add error handling for bad parse cases
1 parent 53fbe60 commit da00e91

File tree

13 files changed

+107
-120
lines changed

13 files changed

+107
-120
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.21)
66

77
# Only set the cxx_standard if it is not set by someone else
88
if (NOT DEFINED CMAKE_CXX_STANDARD)
9-
set(CMAKE_CXX_STANDARD 14)
9+
set(CMAKE_CXX_STANDARD 17)
1010
endif()
1111

1212
# strongly encouraged to enable this globally to avoid conflicts between

fuzz_test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ target_link_libraries(
88
fuzz_tester
99
PRIVATE infiz_options
1010
infiz_warnings
11-
fmt::fmt
11+
libinfiz
1212
-coverage
1313
-fsanitize=fuzzer)
1414
target_compile_options(fuzz_tester PRIVATE -fsanitize=fuzzer)

fuzz_test/fuzz_tester.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
1-
#include <fmt/format.h>
2-
#include <iterator>
3-
#include <utility>
41

5-
[[nodiscard]] auto sum_values(const uint8_t *Data, size_t Size)
6-
{
7-
constexpr auto scale = 1000;
8-
9-
int value = 0;
10-
for (std::size_t offset = 0; offset < Size; ++offset) {
11-
value += static_cast<int>(*std::next(Data, static_cast<long>(offset))) * scale;
12-
}
13-
return value;
14-
}
2+
#include "../src/libinfiz/Evaluator.hpp"
3+
#include <cstdint>
154

165
// Fuzzer that attempts to invoke undefined behavior for signed integer overflow
176
// cppcheck-suppress unusedFunction symbolName=LLVMFuzzerTestOneInput
18-
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
7+
extern "C" auto LLVMFuzzerTestOneInput(const std::uint8_t *Data, std::size_t Size) -> int
198
{
20-
fmt::print("Value sum: {}, len{}\n", sum_values(Data, Size), Size);
9+
[[maybe_unused]] const auto result = evaluate(std::string_view(reinterpret_cast<const char *>(Data), Size));// NOLINT
2110
return 0;
2211
}

src/infiz/infiz.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ auto main(int /*argc*/, char * /*args*/[]) -> int
1414
std::cin.getline(input.data(), max_line - 1, '\n');
1515

1616
while (std::cin.good()) {
17-
StringTokenizer tokenizer(input.data());
18-
const auto answer = evaluateExpression(tokenizer);
17+
const auto answer = evaluate(input.data());
1918
std::cout << "answer: ";
2019

2120
if (answer.getDenominator() == 1) {

src/libinfiz/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ include(GenerateExportHeader)
33

44
add_library(libinfiz
55
Evaluator.cpp
6-
StringTokenizer.cpp)
6+
)
77

88

99

src/libinfiz/Evaluator.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
#include "Evaluator.hpp"
3-
#include <cstdlib>
4-
3+
#include <charconv>
54

65
constexpr auto precedence(Operators input) noexcept -> int
76
{
@@ -123,7 +122,9 @@ auto evaluateExpression(StringTokenizer &tokenizer) -> RationalNumber
123122

124123
default:
125124
operation = false;
126-
numbers.emplace(atoi(next.c_str()), 1);// NOLINT
125+
int parsed= 0;
126+
std::from_chars(next.begin(), next.end(), parsed);
127+
numbers.emplace(parsed, 1);
127128
break;
128129
}
129130

@@ -155,3 +156,9 @@ auto evaluateExpression(StringTokenizer &tokenizer) -> RationalNumber
155156
return { 0, 0 };
156157
}
157158
}
159+
160+
auto evaluate(std::string_view input) -> RationalNumber
161+
{
162+
StringTokenizer tokenizer(input);
163+
return evaluateExpression(tokenizer);
164+
}

src/libinfiz/Evaluator.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
#include "RationalNumber.hpp"
55
#include "Stack.hpp"
66
#include "StringTokenizer.hpp"
7+
#include <string_view>
78

89
enum struct Operators { PLUS_SIGN, CLOSE_PAREN, OPEN_PAREN, MINUS_SIGN, DIVIDE_SIGN, MULTIPLY_SIGN };
910

1011

11-
auto evaluateExpression(StringTokenizer &tokenizer) -> RationalNumber;
12-
void evaluateStacks(Stack<RationalNumber> &numbers, Stack<Operators> &operators);
12+
[[nodiscard]] auto evaluate(std::string_view input) -> RationalNumber;
13+
1314

1415
#endif

src/libinfiz/RationalNumber.hpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define INFIZ_RATIONAL_NUMBER_H
33

44
// RationalNumber.h
5+
#include <numeric>
56

67
/**
78
* A Class that stores the numerator and denominator
@@ -15,40 +16,46 @@ class RationalNumber
1516
: numerator(num), denominator(den)
1617
{}
1718

18-
constexpr auto operator/(const RationalNumber &rhs) const noexcept -> RationalNumber
19+
[[nodiscard]] constexpr auto simplify() const noexcept -> RationalNumber
1920
{
20-
return { numerator * rhs.getDenominator(), denominator * rhs.getNumerator() };
21+
const auto gcd = std::gcd(numerator, denominator);
22+
return {numerator / gcd, denominator / gcd};
2123
}
2224

23-
constexpr auto operator*(const RationalNumber &rhs) const noexcept -> RationalNumber
25+
[[nodiscard]] constexpr auto operator/(const RationalNumber &rhs) const noexcept -> RationalNumber
2426
{
25-
return { numerator * rhs.getNumerator(), denominator * rhs.getDenominator() };
27+
return RationalNumber{ numerator * rhs.getDenominator(), denominator * rhs.getNumerator() }.simplify();
2628
}
2729

28-
constexpr auto operator+(const RationalNumber &rhs) const noexcept -> RationalNumber
30+
[[nodiscard]] constexpr auto operator*(const RationalNumber &rhs) const noexcept -> RationalNumber
2931
{
30-
return { numerator * rhs.getDenominator() + (rhs.getNumerator() * denominator),
31-
denominator * rhs.getDenominator() };
32+
return RationalNumber{ numerator * rhs.getNumerator(), denominator * rhs.getDenominator() }.simplify();
3233
}
3334

34-
constexpr auto operator-(const RationalNumber &rhs) const noexcept -> RationalNumber
35+
[[nodiscard]] constexpr auto operator+(const RationalNumber &rhs) const noexcept -> RationalNumber
3536
{
36-
return { numerator * rhs.getDenominator() - (rhs.getNumerator() * denominator),
37-
denominator * rhs.getDenominator() };
37+
return RationalNumber{ numerator * rhs.getDenominator() + (rhs.getNumerator() * denominator),
38+
denominator * rhs.getDenominator() }.simplify();
3839
}
3940

40-
constexpr auto getDenominator() const noexcept -> int { return denominator; }
41+
[[nodiscard]] constexpr auto operator-(const RationalNumber &rhs) const noexcept -> RationalNumber
42+
{
43+
return RationalNumber{ numerator * rhs.getDenominator() - (rhs.getNumerator() * denominator),
44+
denominator * rhs.getDenominator() }.simplify();
45+
}
46+
47+
[[nodiscard]] constexpr auto getDenominator() const noexcept -> int { return denominator; }
4148

42-
constexpr auto operator-() const -> RationalNumber { return { numerator * -1, denominator }; }
49+
[[nodiscard]] constexpr auto operator-() const -> RationalNumber { return { numerator * -1, denominator }; }
4350

44-
constexpr auto getNumerator() const noexcept -> int { return numerator; }
51+
[[nodiscard]] constexpr auto getNumerator() const noexcept -> int { return numerator; }
4552

46-
constexpr auto getFloat() const noexcept -> float
53+
[[nodiscard]] constexpr auto getFloat() const noexcept -> float
4754
{
4855
return ((static_cast<float>(numerator)) / (static_cast<float>(denominator)));
4956
}
5057

51-
constexpr auto operator==(const RationalNumber &rhs) const noexcept -> bool {
58+
[[nodiscard]] constexpr auto operator==(const RationalNumber &rhs) const noexcept -> bool {
5259
return numerator == rhs.numerator && denominator == rhs.denominator;
5360
}
5461

src/libinfiz/Stack.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ template<typename Contained> class Stack
1717
public:
1818
Stack() = default;
1919

20-
auto empty() const noexcept -> bool { return data.empty(); }
20+
[[nodiscard]] auto empty() const noexcept -> bool { return data.empty(); }
2121

2222
auto pop() -> Contained
2323
{
@@ -36,7 +36,7 @@ template<typename Contained> class Stack
3636

3737
void push(const Contained &newElem) { data.push_back(newElem); }
3838

39-
auto peek() const -> const Contained *
39+
[[nodiscard]] auto peek() const -> const Contained *
4040
{
4141
if (data.empty()) {
4242
return nullptr;

src/libinfiz/StringTokenizer.cpp

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)