summaryrefslogtreecommitdiff
path: root/u8c-check
diff options
context:
space:
mode:
Diffstat (limited to 'u8c-check')
-rw-r--r--u8c-check/CMakeLists.txt63
-rw-r--r--u8c-check/source/check.cc169
-rw-r--r--u8c-check/src/test.cc116
-rw-r--r--u8c-check/src/test0.inl49
-rw-r--r--u8c-check/src/test1.inl24
5 files changed, 232 insertions, 189 deletions
diff --git a/u8c-check/CMakeLists.txt b/u8c-check/CMakeLists.txt
new file mode 100644
index 0000000..8803021
--- /dev/null
+++ b/u8c-check/CMakeLists.txt
@@ -0,0 +1,63 @@
+#
+# Copyright 2021, 2023 Gabriel Bjørnager Jensen.
+#
+# This file is part of u8c.
+#
+# u8c is free software: you can redistribute it
+# and/or modify it under the terms of the GNU
+# Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later
+# version.
+#
+# u8c is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU
+# Lesser General Public License along with u8c. If
+# not, see <https://www.gnu.org/licenses/>.
+#
+
+cmake_minimum_required(VERSION 3.21)
+
+option(U8C_CHECK "build the test program" OFF)
+
+if(U8C_CHECK)
+ set(CMAKE_CXX_STANDARD 17)
+
+ set(CMAKE_CXX_EXTENSIONS OFF)
+
+ add_executable(
+ check
+
+ "source/check.cc"
+ )
+
+ add_dependencies(
+ check
+
+ u8c
+ )
+
+ target_link_libraries(
+ check
+
+ u8c
+ )
+
+ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang|GNU")
+ target_compile_options(
+ check PRIVATE
+
+ -Og
+ -Wall
+ -Wextra
+ -Wpedantic
+ -fdiagnostics-color=always
+ -g
+ )
+ endif()
+endif()
diff --git a/u8c-check/source/check.cc b/u8c-check/source/check.cc
new file mode 100644
index 0000000..52adcad
--- /dev/null
+++ b/u8c-check/source/check.cc
@@ -0,0 +1,169 @@
+#include <climits>
+#include <cstdint>
+#include <cstdlib>
+#include <iomanip>
+#include <iostream>
+#include <string>
+#include <type_traits>
+#include <u8c/character.h>
+#include <u8c/format.h>
+
+using namespace ::std::literals::string_literals;
+
+int main() {
+ int unsigned error_count = 0x0u;
+
+ auto const log_unit = [](::std::string const& identifier) noexcept -> void {
+ ::std::cerr <<"\n\x1B[38;5;75mtesting\x1B[0m " << identifier <<"\n\n";
+ };
+
+ auto const check = [&error_count](long const line, auto const& left_value, auto const& right_value) {
+ ::std::cerr << " " << ::std::setbase(0xA) << line << ". ";
+
+ auto const okay = [](auto const& left_reference, auto const& right_reference) -> bool {
+ auto const get_value = [](auto const& reference) -> auto {
+ using T = ::std::remove_cv_t<::std::remove_reference_t<decltype (left_value)>>;
+
+ if constexpr (::std::is_same_v<T, char>) {
+ return static_cast<::std::uintmax_t>(static_cast<char unsigned>(reference));
+ } else if constexpr (::std::is_signed_v<T>) {
+ return static_cast<::std::intmax_t>(reference);
+ } else if constexpr (::std::is_unsigned_v<T>) {
+ return static_cast<::std::uintmax_t>(reference);
+ } else {
+ return static_cast<T>(reference);
+ }
+ };
+
+ auto const left_value = get_value(left_reference);
+ auto const right_value = get_value(right_reference);
+
+ ::std::cerr << "" << ::std::setbase(0x10) << left_value << " equals " << right_value << "... ";
+
+ return left_value == right_value;
+ }(left_value, right_value);
+
+ if (!okay) {
+ ::std::cerr << "\x1B[38;5;161mfalse\x1B[0m\n";
+ ++error_count;
+ } else {
+ ::std::cerr <<"\x1B[38;5;77mtrue\x1B[0m\n";
+ }
+ };
+ #define check(left_value, right_value) (check(__LINE__, (left_value), (right_value)))
+
+ ::std::cerr << "u8c-check " << u8c_VERSION << "\n";
+
+ [&] {
+ log_unit("UTF-8");
+
+ ::std::uint_least32_t const source[] {
+ UINT32_C(0x0026),
+ UINT32_C(0x00F0),
+ UINT32_C(0x218A),
+ UINT32_C(0x0001F480),
+ UINT32_C(0xD800),
+ UINT32_C(0x0010FFFF),
+ UINT32_C(0x00110000),
+ };
+ auto const source_length = sizeof (source) / sizeof (source[0x0]);
+
+ size_t const utf8_buffer_length = ::u8c_encode_utf8_length(source, source_length);
+ check(utf8_buffer_length, 0x14u);
+
+ auto const utf8_buffer = new char[utf8_buffer_length];
+
+ ::u8c_encode_utf8(utf8_buffer, source, source_length);
+
+ check(utf8_buffer[0x00], '\x26');
+ check(utf8_buffer[0x01], '\xC3');
+ check(utf8_buffer[0x02], '\xB0');
+ check(utf8_buffer[0x03], '\xE2');
+ check(utf8_buffer[0x04], '\x86');
+ check(utf8_buffer[0x05], '\x8A');
+ check(utf8_buffer[0x06], '\xF0');
+ check(utf8_buffer[0x07], '\x9F');
+ check(utf8_buffer[0x08], '\x92');
+ check(utf8_buffer[0x09], '\x80');
+ check(utf8_buffer[0x0A], '\xEF');
+ check(utf8_buffer[0x0B], '\xBF');
+ check(utf8_buffer[0x0C], '\xBD');
+ check(utf8_buffer[0x0D], '\xF4');
+ check(utf8_buffer[0x0E], '\x8F');
+ check(utf8_buffer[0x0F], '\xBF');
+ check(utf8_buffer[0x10], '\xBF');
+ check(utf8_buffer[0x11], '\xEF');
+ check(utf8_buffer[0x12], '\xBF');
+ check(utf8_buffer[0x13], '\xBD');
+
+ auto const utf32_buffer_length = ::u8c_decode_utf8_length(utf8_buffer, utf8_buffer_length);
+ check(utf32_buffer_length, 0x7u);
+
+ auto const utf32_buffer = new ::std::uint_least32_t[utf32_buffer_length];
+
+ ::u8c_decode_utf8(utf32_buffer, utf8_buffer, utf8_buffer_length);
+
+ check(utf32_buffer[0x0], UINT32_C(0x0026));
+ check(utf32_buffer[0x1], UINT32_C(0x00F0));
+ check(utf32_buffer[0x2], UINT32_C(0x218A));
+ check(utf32_buffer[0x3], UINT32_C(0x0001F480));
+ check(utf32_buffer[0x4], UINT32_C(0xFFFD));
+
+ delete[] utf8_buffer;
+ delete[] utf32_buffer;
+ }();
+
+ [&] {
+ log_unit("UTF-16");
+
+ ::std::uint_least32_t const source[] {
+ UINT32_C(0x0026),
+ UINT32_C(0x00F0),
+ UINT32_C(0x218A),
+ UINT32_C(0x0001F480),
+ UINT32_C(0xD800),
+ UINT32_C(0x0010FFFF),
+ UINT32_C(0x00110000),
+ };
+ auto const source_length = sizeof (source) / sizeof (source[0x0]);
+
+ auto const utf16_buffer_length = ::u8c_encode_utf16_length(source, source_length);
+ check(utf16_buffer_length, 0x9u);
+
+ auto const utf16_buffer = new ::std::uint_least16_t[utf16_buffer_length];
+
+ ::u8c_encode_utf16(utf16_buffer, source, source_length);
+
+ check(utf16_buffer[0x0], UINT16_C(0x0026));
+ check(utf16_buffer[0x1], UINT16_C(0x00F0));
+ check(utf16_buffer[0x2], UINT16_C(0x218A));
+ check(utf16_buffer[0x3], UINT16_C(0xD83D));
+ check(utf16_buffer[0x4], UINT16_C(0xDC80));
+ check(utf16_buffer[0x5], UINT16_C(0xFFFD));
+ check(utf16_buffer[0x6], UINT16_C(0xDBFF));
+ check(utf16_buffer[0x7], UINT16_C(0xDFFF));
+ check(utf16_buffer[0x8], UINT16_C(0xFFFD));
+
+ auto const utf32_buffer_length = ::u8c_decode_utf16_length(utf16_buffer, utf16_buffer_length);
+ check(utf32_buffer_length, 0x7u);
+
+ auto const utf32_buffer = new ::std::uint_least32_t[utf32_buffer_length];
+
+ ::u8c_decode_utf16(utf32_buffer, utf16_buffer, utf16_buffer_length);
+
+ check(utf32_buffer[0x0], UINT32_C(0x0026));
+ check(utf32_buffer[0x1], UINT32_C(0x00F0));
+ check(utf32_buffer[0x2], UINT32_C(0x218A));
+ check(utf32_buffer[0x3], UINT32_C(0x0001F480));
+ check(utf32_buffer[0x4], UINT32_C(0xFFFD));
+ check(utf32_buffer[0x5], UINT32_C(0x0010FFFF));
+ check(utf32_buffer[0x6], UINT32_C(0xFFFD));
+
+ delete[] utf16_buffer;
+ delete[] utf32_buffer;
+ }();
+
+ ::std::cerr << "\ndone - " << error_count << " error(s)\n";
+
+ return error_count != 0x0u ? EXIT_FAILURE : EXIT_SUCCESS;
+} \ No newline at end of file
diff --git a/u8c-check/src/test.cc b/u8c-check/src/test.cc
deleted file mode 100644
index 1b600aa..0000000
--- a/u8c-check/src/test.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-#if defined(NDEBUG)
-#undef NDEBUG
-#endif
-
-#include <chrono> /* std::chrono::duration, std::chrono::high_resolution_clock */
-#include <cstdlib> /* EXIT_FAILURE, EXIT_SUCCESS, std::exit */
-#include <cstring> /* std::strcmp */
-#include <iostream> /* std::cerr, std::cout, std::endl */
-#include <limits> /* std::numeric_limits */
-#include <u8c/u8c>
-
-# include "test0.inl"
-# include "test1.inl"
-
-static_assert(u8c::abs(-0x1) == 0x1);
-static_assert(u8c::abs(-0x1p0) == 0x1p0);
-static_assert(u8c::abs(-0x100p0) == 0x100p0);
-
-static_assert(u8c::fma(0x10,0x10,0x100) == 0x200);
-
-static_assert(!u8c::isinf(0x0));
-static_assert(u8c::isinf(std::numeric_limits<float>::infinity()));
-
-static_assert(!u8c::isnan(0x0));
-static_assert(u8c::isnan(std::numeric_limits<float>::quiet_NaN()));
-
-static_assert(u8c::isprime(0x2u));
-static_assert(u8c::isprime(0x3u));
-static_assert(!u8c::isprime(0x4u));
-static_assert(u8c::isprime(0x5u));
-static_assert(!u8c::isprime(0x6u));
-static_assert(u8c::isprime(0x7u));
-static_assert(!u8c::isprime(0x8u));
-static_assert(!u8c::isprime(0x9u));
-static_assert(!u8c::isprime(0xAu));
-static_assert(u8c::isprime(0xBu));
-static_assert(!u8c::isprime(0xCu));
-static_assert(u8c::isprime(0xDu));
-static_assert(!u8c::isprime(0xEu));
-static_assert(!u8c::isprime(0xFu));
-
-static_assert(u8c::pow(0x1,0x10000) == 0x1);
-static_assert(u8c::pow(0x2,0x2) == 0x4);
-static_assert(u8c::pow(0x2,0x4) == 0x10);
-static_assert(u8c::pow(0x2,0x10) == 0x10000);
-static_assert(u8c::pow(0x3,0x3) == 0x1B);
-
-static_assert(u8c::quota(0x1,0x3) < u8c::quota<>::inf());
-static_assert(u8c::quota(0x1,0x3) == u8c::quota(0x2,0x6));
-static_assert(u8c::quota<>::inf() == u8c::quota<>::inf());
-static_assert(u8c::quota<>::nan() != u8c::quota<>::nan());
-
-static_assert(u8c::cstrlen("This is a string!") == 0x11uz);
-static_assert(u8c::cstrlen("Das war ein Befehl!") == 0x13uz);
-
-static_assert(u8c::cstrcmp("Clang","Clang") == u8c_bytec(0x0));
-static_assert(u8c::cstrcmp("Clang","GCC") == u8c_bytec(0x1));
-static_assert(u8c::cstrcmp("GCC","Clang") == u8c_bytec(-0x1));
-static_assert(u8c::cstrcmp("GCC","GCC") == u8c_bytec(0x0));
-
-auto main(int const argc,char const * const * const argv) -> int {
- int constexpr maxtestn = 0x1;
- auto gettestnm = [](int const _n) {
- switch (_n) {
- [[unlikely]] default:
- return "N/A";
- case 0x0:
- return "Array Stress-testing";
- case 0x1:
- return "Strings";
- }
- };
- auto helpscrn = [&](char const * const _prognm) {
- std::cout << "u8c-test: Test u8c" << std::endl;
- std::cout << "Usage: " << _prognm << " [test number]" << std::endl;
- std::cout << std::endl;
- std::cout << "Test numbers:" << std::endl;
- for (int n = 0x0;n <= maxtestn;n += 0x1) {
- std::cout << "\t " << n << " - \"" << gettestnm(n) << "\"" << std::endl;
- }
- std::cout << std::endl;
- std::cout << "u8c version: " << u8c::ver << std::endl;
- };
- auto test = [&](int const _n) {
- auto const testnm = gettestnm(_n);
- std::cout << ":: \u001B[95mTesting\u001B[0m test #" << _n << " \u001B[3m\"" << testnm << "\"\u001B[0m..." << std::endl << std::endl;
- auto begin = std::chrono::high_resolution_clock::now();
- switch (_n) {
- [[unlikely]] default:
- std::exit(EXIT_FAILURE);
- case 0x0:
- ::test0();
- break;
- case 0x1:
- ::test1();
- break;
- }
- auto const end = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double> const tmdiff = end - begin;
- std::cout << std::endl << ":: \u001B[96mDone\u001B[0m testing test #" << _n << " \u001B[3m\"" << testnm << "\"\u001B[0m (took " << tmdiff.count() << " seconds)." << std::endl;
- };
- if (argc > 0x1) {
- if (!std::strcmp(argv[0x1uz],"--help")) {
- helpscrn(argv[0x0uz]);
- std::exit(EXIT_SUCCESS);
- }
- else {
- std::cerr << "Invalid argument \"\u001B[3m" << argv[0x1uz] << "\"\u001B[0m." << std::endl;
- std::exit(EXIT_FAILURE);
- }
- }
- for (int n = 0x0;n <= maxtestn;n += 0x1) {
- test(n);
- }
- std::exit(EXIT_SUCCESS);
-}
diff --git a/u8c-check/src/test0.inl b/u8c-check/src/test0.inl
deleted file mode 100644
index 5b4db6c..0000000
--- a/u8c-check/src/test0.inl
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <iostream> /* std::cerr, std::endl */
-#include <limits> /* std::numeric_limits */
-#include <random> /* std::random_device, std::uniform_int_distribution */
-#include <u8c/arr>
-
-auto test0() -> void {
- std::cerr << "Constructing array of 256 elements, each with a value of 15...";
- u8c::arr<int> arr(0x100uz,0xF);
- u8c_assert(arr.sz() == 0x100uz);
- u8c_assert(static_cast<u8c::size>(arr.end() - arr.begin()) == arr.sz());
- for (auto const elm : arr) {
- u8c_assert(elm == 0xF);
- }
- std::cerr << " okay." << std::endl;
- std::random_device rd;
- {
- std::uniform_int_distribution<int> distr(0x0,std::numeric_limits<int>::max());
- for (u8c::byte n = u8c_bytec(0x0);n <= u8c_bytec(0x10);n += u8c_ubytec(0x1)) {
- auto const val = distr(rd);
- std::cerr << "Filling array with the value of " << val << "...";
- arr.fill(val);
- for (auto const elm : arr) {
- u8c_assert(elm == val);
- }
- std::cerr << " okay." << std::endl;
- }
- }
- {
- std::uniform_int_distribution<u8c::size> distr(0x1,0xFFF);
- for (u8c::byte n = u8c_bytec(0x0);n <= u8c_bytec(0x4);n += u8c_ubytec(0x1)) {
- auto const sz = distr(rd);
- std::cerr << "Allocating the array to the size of " << sz << "...";
- arr.alloc(sz);
- u8c_assert(arr.sz() == sz);
- std::cerr << " okay." << std::endl;
- }
- }
- std::cerr << "Doing some additionel tests...";
- arr.alloc(0x2uz);
- u8c_assert(arr.sz() == 0x2uz);
- arr.fill(0xF);
- u8c_assert(arr[0x0uz] == 0xF);
- u8c_assert(arr[0x1uz] == 0xF);
- arr.realloc(0x4uz);
- u8c_assert(arr.sz() == 0x4uz);
- u8c_assert(arr[0x0uz] == 0xF);
- u8c_assert(arr[0x1uz] == 0xF);
- std::cerr << " okay." << std::endl;
-}
diff --git a/u8c-check/src/test1.inl b/u8c-check/src/test1.inl
deleted file mode 100644
index 4e2a18e..0000000
--- a/u8c-check/src/test1.inl
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <cstdint> /* u8c_uint32c, u8c_ubytec, std::int_fast8_t, u8c::uint32 */
-#include <iomanip> /* std::hex */
-#include <iostream> /* std::cout, std::endl */
-#include <random> /* std::random_device */
-
-auto test1() -> void {
- std::random_device rd;
- std::uniform_int_distribution<char32_t> distr(u8c_uint32c(0x0),u8c_uint32c(0x100));
- for(std::int_fast8_t n = u8c_bytec(0x0);n <= u8c_bytec(0x4);n += u8c_ubytec(0x1)) {
- auto const chr = distr(rd);
- std::cout << "U+" << std::hex << static_cast<u8c::uint32>(chr) << " (\"" << u8c::uninm(chr) << "\" @ \"" << u8c::uniblk(chr) << "\")" << std::endl;
- std::cout << "Is alphanumeric: " << u8c::isalnum(chr) << std::endl;
- std::cout << "Is alphabetic: " << u8c::isalpha(chr) << std::endl;
- std::cout << "Is control character: " << u8c::iscntrl(chr) << std::endl;
- std::cout << "Is digit: " << u8c::isdigit(chr) << std::endl;
- std::cout << "Is lowercase: " << u8c::islower(chr) << std::endl;
- std::cout << "Is punctuation mark: " << u8c::ispunct(chr) << std::endl;
- std::cout << "Is whitespace: " << u8c::isspace(chr) << std::endl;
- std::cout << "Is surrogate point: " << u8c::issurro(chr) << std::endl;
- std::cout << "Is uppercase: " << u8c::isupper(chr) << std::endl;
- std::cout << "Is hexadecimal digit: " << u8c::isxdigit(chr) << std::endl;
- std::cout << std::endl;
- }
-}