summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLenny Maiorani <lenny@colorado.edu>2021-04-18 11:06:36 -0600
committerAndreas Kling <kling@serenityos.org>2021-04-18 22:09:25 +0200
commitd462a561630f9768d4c346a73689e30c43f3a992 (patch)
tree5bc04617ec1952f7903105b506b06ba55e91bb34
parent0ac02b9084c0fa02ffa64397dd22a6155db13ba6 (diff)
downloadserenity-d462a561630f9768d4c346a73689e30c43f3a992.zip
AK/Hex: Decode hex digit in constexpr context
Problem: - Hex digit decoding is not `constexpr`, but can be. Solution: - Move the body of the function to the header and decorate with `constexpr`. - Provide tests for run-time and compile-time evaluation.
-rw-r--r--AK/Hex.cpp11
-rw-r--r--AK/Hex.h11
-rw-r--r--AK/Tests/CMakeLists.txt3
-rw-r--r--AK/Tests/TestHex.cpp83
4 files changed, 94 insertions, 14 deletions
diff --git a/AK/Hex.cpp b/AK/Hex.cpp
index 0e3c367bff..f764eda27e 100644
--- a/AK/Hex.cpp
+++ b/AK/Hex.cpp
@@ -35,17 +35,6 @@
namespace AK {
-u8 decode_hex_digit(char digit)
-{
- if (digit >= '0' && digit <= '9')
- return digit - '0';
- if (digit >= 'a' && digit <= 'f')
- return 10 + (digit - 'a');
- if (digit >= 'A' && digit <= 'F')
- return 10 + (digit - 'A');
- return 255;
-}
-
Optional<ByteBuffer> decode_hex(const StringView& input)
{
if ((input.length() % 2) != 0)
diff --git a/AK/Hex.h b/AK/Hex.h
index 2402973904..440e534262 100644
--- a/AK/Hex.h
+++ b/AK/Hex.h
@@ -33,7 +33,16 @@
namespace AK {
-u8 decode_hex_digit(char);
+constexpr u8 decode_hex_digit(char digit)
+{
+ if (digit >= '0' && digit <= '9')
+ return digit - '0';
+ if (digit >= 'a' && digit <= 'f')
+ return 10 + (digit - 'a');
+ if (digit >= 'A' && digit <= 'F')
+ return 10 + (digit - 'A');
+ return 255;
+}
Optional<ByteBuffer> decode_hex(const StringView&);
diff --git a/AK/Tests/CMakeLists.txt b/AK/Tests/CMakeLists.txt
index 6948c50875..486a24e576 100644
--- a/AK/Tests/CMakeLists.txt
+++ b/AK/Tests/CMakeLists.txt
@@ -1,5 +1,3 @@
-
-
set(AK_TEST_SOURCES
TestAllOf.cpp
TestAnyOf.cpp
@@ -26,6 +24,7 @@ set(AK_TEST_SOURCES
TestHashFunctions.cpp
TestHashMap.cpp
TestHashTable.cpp
+ TestHex.cpp
TestIPv4Address.cpp
TestIndexSequence.cpp
TestIntrusiveRedBlackTree.cpp
diff --git a/AK/Tests/TestHex.cpp b/AK/Tests/TestHex.cpp
new file mode 100644
index 0000000000..b971f82115
--- /dev/null
+++ b/AK/Tests/TestHex.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2020, the SerenityOS developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <AK/TestSuite.h>
+
+#include <AK/Hex.h>
+
+TEST_CASE(should_decode_hex_digit)
+{
+ EXPECT_EQ(0u, decode_hex_digit('0'));
+ EXPECT_EQ(1u, decode_hex_digit('1'));
+ EXPECT_EQ(2u, decode_hex_digit('2'));
+ EXPECT_EQ(3u, decode_hex_digit('3'));
+ EXPECT_EQ(4u, decode_hex_digit('4'));
+ EXPECT_EQ(5u, decode_hex_digit('5'));
+ EXPECT_EQ(6u, decode_hex_digit('6'));
+ EXPECT_EQ(7u, decode_hex_digit('7'));
+ EXPECT_EQ(8u, decode_hex_digit('8'));
+ EXPECT_EQ(9u, decode_hex_digit('9'));
+ EXPECT_EQ(10u, decode_hex_digit('a'));
+ EXPECT_EQ(11u, decode_hex_digit('b'));
+ EXPECT_EQ(12u, decode_hex_digit('c'));
+ EXPECT_EQ(13u, decode_hex_digit('d'));
+ EXPECT_EQ(14u, decode_hex_digit('e'));
+ EXPECT_EQ(15u, decode_hex_digit('f'));
+ EXPECT_EQ(10u, decode_hex_digit('A'));
+ EXPECT_EQ(11u, decode_hex_digit('B'));
+ EXPECT_EQ(12u, decode_hex_digit('C'));
+ EXPECT_EQ(13u, decode_hex_digit('D'));
+ EXPECT_EQ(14u, decode_hex_digit('E'));
+ EXPECT_EQ(15u, decode_hex_digit('F'));
+}
+
+TEST_CASE(should_constexpr_decode_hex_digit)
+{
+ static_assert(0u == decode_hex_digit('0'));
+ static_assert(1u == decode_hex_digit('1'));
+ static_assert(2u == decode_hex_digit('2'));
+ static_assert(3u == decode_hex_digit('3'));
+ static_assert(4u == decode_hex_digit('4'));
+ static_assert(5u == decode_hex_digit('5'));
+ static_assert(6u == decode_hex_digit('6'));
+ static_assert(7u == decode_hex_digit('7'));
+ static_assert(8u == decode_hex_digit('8'));
+ static_assert(9u == decode_hex_digit('9'));
+ static_assert(10u == decode_hex_digit('a'));
+ static_assert(11u == decode_hex_digit('b'));
+ static_assert(12u == decode_hex_digit('c'));
+ static_assert(13u == decode_hex_digit('d'));
+ static_assert(14u == decode_hex_digit('e'));
+ static_assert(15u == decode_hex_digit('f'));
+ static_assert(10u == decode_hex_digit('A'));
+ static_assert(11u == decode_hex_digit('B'));
+ static_assert(12u == decode_hex_digit('C'));
+ static_assert(13u == decode_hex_digit('D'));
+ static_assert(14u == decode_hex_digit('E'));
+ static_assert(15u == decode_hex_digit('F'));
+}
+
+TEST_MAIN(Hex)