ascii: add hex conversion and unit tests
This commit is contained in:
parent
7fc5eb3b17
commit
813600e774
|
@ -435,6 +435,7 @@ if (TESTS)
|
||||||
|
|
||||||
list (
|
list (
|
||||||
APPEND TEST_BIN
|
APPEND TEST_BIN
|
||||||
|
ascii
|
||||||
algo/sort
|
algo/sort
|
||||||
alloc/aligned
|
alloc/aligned
|
||||||
alloc/arena
|
alloc/arena
|
||||||
|
|
36
ascii.hpp
36
ascii.hpp
|
@ -51,6 +51,42 @@ namespace util::ascii {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
constexpr inline
|
||||||
|
bool
|
||||||
|
is_lower (char c) noexcept
|
||||||
|
{
|
||||||
|
return c >= 'a' && c <= 'z';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
constexpr inline
|
||||||
|
bool
|
||||||
|
is_hex (const char c) noexcept
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case '0'...'9': return true;
|
||||||
|
case 'a'...'f': return true;
|
||||||
|
case 'A'...'F': return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
constexpr inline
|
||||||
|
unsigned
|
||||||
|
from_hex (char c)
|
||||||
|
{
|
||||||
|
return c >= '0' && c <= '9' ? (c - '0' ) :
|
||||||
|
c >= 'a' && c <= 'f' ? (c - 'a' + 10) :
|
||||||
|
c >= 'A' && c <= 'F' ? (c - 'A' + 10) :
|
||||||
|
throw std::invalid_argument ("character is not hexademical");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
constexpr inline
|
constexpr inline
|
||||||
char
|
char
|
||||||
|
|
79
test/ascii.cpp
Normal file
79
test/ascii.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2017 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tap.hpp"
|
||||||
|
|
||||||
|
#include "ascii.hpp"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int, char**)
|
||||||
|
{
|
||||||
|
util::TAP::logger tap;
|
||||||
|
|
||||||
|
static constexpr bool T = true;
|
||||||
|
static constexpr bool F = false;
|
||||||
|
|
||||||
|
static constexpr struct {
|
||||||
|
char character;
|
||||||
|
|
||||||
|
bool is_digit;
|
||||||
|
bool is_hex;
|
||||||
|
bool is_upper;
|
||||||
|
bool is_lower;
|
||||||
|
bool is_space;
|
||||||
|
|
||||||
|
int integer;
|
||||||
|
unsigned hexadecimal;
|
||||||
|
|
||||||
|
const char *msg;
|
||||||
|
} TESTS[] = {
|
||||||
|
{ '/', F, F, F, F, F, 0, 0, "/" }, // one below '0'
|
||||||
|
{ '0', T, T, F, F, F, 0, 0, "0" },
|
||||||
|
{ '9', T, T, F, F, F, 9, 9, "9" },
|
||||||
|
{ ':', F, F, F, F, F, 0, 0, ":" }, // one above '9'
|
||||||
|
{ '`', F, F, F, F, F, 0, 0, "`" }, // one below 'a'
|
||||||
|
{ 'a', F, T, F, T, F, 0, 10, "a" },
|
||||||
|
{ 'f', F, T, F, T, F, 0, 15, "f" },
|
||||||
|
{ 'g', F, F, F, T, F, 0, 0, "g" },
|
||||||
|
{ 'A', F, T, T, F, F, 0, 10, "A" },
|
||||||
|
{ 'F', F, T, T, F, F, 0, 15, "F" },
|
||||||
|
{ 'G', F, F, T, F, F, 0, 0, "G" },
|
||||||
|
|
||||||
|
{ ' ', F, F, F, F, T, 0, 0, "space" },
|
||||||
|
{ '\t', F, F, F, F, T, 0, 0, "tab" },
|
||||||
|
{ '\n', F, F, F, F, T, 0, 0, "newline" },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TRY_BOOL(X) [&] () -> bool { try { return X; } catch (...) { return false; }; } ()
|
||||||
|
|
||||||
|
for (auto &t: TESTS) {
|
||||||
|
bool is_digit = TRY_BOOL(util::ascii::is_digit (t.character)) == t.is_digit;
|
||||||
|
bool is_hex = TRY_BOOL(util::ascii::is_hex (t.character)) == t.is_hex;
|
||||||
|
bool is_upper = TRY_BOOL(util::ascii::is_upper (t.character)) == t.is_upper;
|
||||||
|
bool is_lower = TRY_BOOL(util::ascii::is_lower (t.character)) == t.is_lower;
|
||||||
|
bool is_space = TRY_BOOL(util::ascii::is_space (t.character)) == t.is_space;
|
||||||
|
|
||||||
|
bool integer = !t.is_digit || util::ascii::to_integer (t.character) == t.integer;
|
||||||
|
bool hexadecimal = !t.is_hex || util::ascii::from_hex (t.character) == t.hexadecimal;
|
||||||
|
|
||||||
|
tap.expect (
|
||||||
|
is_digit && is_hex && is_upper && is_lower && is_space && integer && hexadecimal,
|
||||||
|
"%s", t.msg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tap.status ();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user