summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Tanous <edtanous@google.com>2022-01-25 05:56:47 +0300
committerEd Tanous <ed@tanous.net>2022-01-28 22:43:31 +0300
commitbb05f2227d53d590534d1df6e6a622e13cea76ae (patch)
tree8751dae62b0d3dafc13a52e0e498efb8ca47b2c9
parent665479d4f1c39f1c8308a5917d0e060f605275af (diff)
downloadbmcweb-bb05f2227d53d590534d1df6e6a622e13cea76ae.tar.xz
Simplify human sort
Clang-tidy correctly noted that this method was overly complex and could be simplified. This commit does exactly that. Tested: Unit tests run and passing. Signed-off-by: Ed Tanous <edtanous@google.com> Change-Id: Ia225f0d8cc5942f776bc8d5b48ca91de40596451
-rw-r--r--include/human_sort.hpp87
1 files changed, 41 insertions, 46 deletions
diff --git a/include/human_sort.hpp b/include/human_sort.hpp
index 0d6e35d8a5..02018b1e14 100644
--- a/include/human_sort.hpp
+++ b/include/human_sort.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <charconv>
#include <string_view>
namespace details
@@ -12,73 +13,67 @@ inline bool simpleIsDigit(const char c)
return c >= '0' && c <= '9';
}
+enum class ModeType
+{
+ STRING,
+ NUMBER
+};
+
} // namespace details
inline int alphanumComp(const std::string_view left,
const std::string_view right)
{
- enum class ModeType
- {
- STRING,
- NUMBER
- } mode = ModeType::STRING;
std::string_view::const_iterator l = left.begin();
std::string_view::const_iterator r = right.begin();
+ details::ModeType mode = details::ModeType::STRING;
+
while (l != left.end() && r != right.end())
{
- if (mode == ModeType::STRING)
+ if (mode == details::ModeType::STRING)
{
- while (l != left.end() && r != right.end())
+ // check if this are digit characters
+ const bool lDigit = details::simpleIsDigit(*l);
+ const bool rDigit = details::simpleIsDigit(*r);
+ // if both characters are digits, we continue in NUMBER mode
+ if (lDigit && rDigit)
+ {
+ mode = details::ModeType::NUMBER;
+ continue;
+ }
+ // if only the left character is a digit, we have a result
+ if (lDigit)
+ {
+ return -1;
+ } // if only the right character is a digit, we have a result
+ if (rDigit)
{
- // check if this are digit characters
- const bool lDigit = details::simpleIsDigit(*l);
- const bool rDigit = details::simpleIsDigit(*r);
- // if both characters are digits, we continue in NUMBER mode
- if (lDigit && rDigit)
- {
- mode = ModeType::NUMBER;
- break;
- }
- // if only the left character is a digit, we have a result
- if (lDigit)
- {
- return -1;
- } // if only the right character is a digit, we have a result
- if (rDigit)
- {
- return +1;
- }
- // compute the difference of both characters
- const int diff = *l - *r;
- // if they differ we have a result
- if (diff != 0)
- {
- return diff;
- }
- // otherwise process the next characters
- l++;
- r++;
+ return +1;
}
+ // compute the difference of both characters
+ const int diff = *l - *r;
+ // if they differ we have a result
+ if (diff != 0)
+ {
+ return diff;
+ }
+ // otherwise process the next characters
+ l++;
+ r++;
}
else // mode==NUMBER
{
// get the left number
int lInt = 0;
- while (l != left.end() && details::simpleIsDigit(*l))
- {
- lInt = lInt * 10 + static_cast<int>(*l) - '0';
- ++l;
- }
+ auto fc = std::from_chars(&(*l), &(*left.end()), lInt);
+ l += std::distance(l, fc.ptr);
// get the right number
int rInt = 0;
- while (r != right.end() && details::simpleIsDigit(*r))
- {
- rInt = rInt * 10 + static_cast<int>(*r) - '0';
- ++r;
- }
+ fc = std::from_chars(&(*r), &(*right.end()), rInt);
+ r += std::distance(r, fc.ptr);
// if the difference is not equal to zero, we have a comparison
// result
@@ -89,7 +84,7 @@ inline int alphanumComp(const std::string_view left,
}
// otherwise we process the next substring in STRING mode
- mode = ModeType::STRING;
+ mode = details::ModeType::STRING;
}
}
if (r == right.end() && l == left.end())