diff --git a/README_EN.md b/README_EN.md deleted file mode 100644 index 5fe51ad..0000000 --- a/README_EN.md +++ /dev/null @@ -1,12 +0,0 @@ -![Build badge](https://github.com/xiran56/NTL/actions/workflows/build.yml/badge.svg) -[![Codacy Badge](https://app.codacy.com/project/badge/Grade/8910e89f85194265a1b9b06e7a1a9f35)](https://app.codacy.com/gh/xiran56/NTL/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) - -# NTL - -Header-only библиотека для работы с числами и цифрами в разных представлениях (int, char) и разных системах сисления. - -Особенности библиотеки: -- Стандарт C++17 (планируется добавить совместимость вплоть до C++11) -- Хорошая переносимость (в стандартных Traits не используются интрисики, SIMD) -- Хорошая совместимость с STL -- С помощью своих Traits легко внести свой функционал diff --git a/include/ntl/impl/AsciiDigitTable.hh b/include/ntl/impl/AsciiDigitTable.hh new file mode 100644 index 0000000..b15f407 --- /dev/null +++ b/include/ntl/impl/AsciiDigitTable.hh @@ -0,0 +1,77 @@ +#pragma once + +#include +#include + +namespace ntl { + namespace impl { + struct InvalidDigit : std::integral_constant {}; + + template + struct AsciiDigitTable : std::integral_constant {}; + + template<> struct AsciiDigitTable<'0'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'1'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'2'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'3'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'4'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'5'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'6'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'7'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'8'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'9'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'A'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'B'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'C'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'D'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'E'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'F'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'G'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'H'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'I'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'J'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'K'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'L'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'M'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'N'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'O'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'P'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'Q'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'R'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'S'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'T'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'U'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'V'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'W'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'X'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'Y'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'Z'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'a'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'b'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'c'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'d'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'e'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'f'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'g'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'h'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'i'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'j'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'k'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'l'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'m'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'n'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'o'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'p'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'q'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'r'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'s'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'t'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'u'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'v'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'w'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'x'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'y'> : std::integral_constant {}; + template<> struct AsciiDigitTable<'z'> : std::integral_constant {}; + + } +} diff --git a/include/ntl/impl/CharConv.hh b/include/ntl/impl/CharConv.hh new file mode 100644 index 0000000..6273fa4 --- /dev/null +++ b/include/ntl/impl/CharConv.hh @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "Helpers.hh" + +namespace ntl::impl { + template + constexpr auto toInt(const char *str) -> std::enable_if_t, Integer> + { + if (!str) + static_assert(alwaysFalse, "Forwarded nullptr!"); + + Integer result { 0 }; + + while (*str) { + result *= B; + + if constexpr (B <= 10) + if ('0' > str && str > ('0' + (B - 1))) + } + } +} diff --git a/include/ntl/impl/CharsToNumber.hh b/include/ntl/impl/CharsToNumber.hh new file mode 100644 index 0000000..46c8327 --- /dev/null +++ b/include/ntl/impl/CharsToNumber.hh @@ -0,0 +1,31 @@ +#pragma once + +#include "AsciiDigitTable.hh" +#include "Helpers.hh" +#include +#include + +namespace ntl { + namespace impl { + template + struct CharsToNumber; + + template + struct CharsToNumber + : std::integral_constant::value, + Negative, Base, Chars...>::value> + { static_assert(AsciiDigitTable::value != InvalidDigit::value && AsciiDigitTable::value < Base, "Invalid digit!"); }; + + template + struct CharsToNumber + : std::integral_constant::value> + { static_assert(Prev == 0, "\"-\" isn't in begin of number"); }; + + template + struct CharsToNumber : std::integral_constant { }; + + template + struct CharsToNumber : std::integral_constant { }; + } +} diff --git a/include/ntl/impl/Helpers.hh b/include/ntl/impl/Helpers.hh index e2feab1..aa554cf 100644 --- a/include/ntl/impl/Helpers.hh +++ b/include/ntl/impl/Helpers.hh @@ -1,12 +1,19 @@ #pragma once -namespace ntl::impl { +#include + +namespace ntl { template - inline constexpr bool alwaysFalse { false }; + struct AlwaysFalse : std::false_type {}; + + template + struct AlwaysFalseValue : std::false_type {}; - class Traits { - public: - Traits() = delete; - ~Traits() = delete; - }; + namespace impl { + class Traits { + public: + Traits() = delete; + ~Traits() = delete; + }; + } } diff --git a/include/ntl/impl/NumberDigitConvTraits.hh b/include/ntl/impl/NumberDigitConvTraits.hh index 1c8f023..5945d17 100644 --- a/include/ntl/impl/NumberDigitConvTraits.hh +++ b/include/ntl/impl/NumberDigitConvTraits.hh @@ -17,7 +17,7 @@ namespace ntl::impl::traits { using BaseType = std::uint8_t; using DigitType = std::uint8_t; - static SizeType countDigits(T n, BaseType base) { + static constexpr SizeType countDigits(T n, BaseType base) { SizeType result { 0 }; if constexpr (minusCounted) @@ -34,17 +34,21 @@ namespace ntl::impl::traits { } template - inline static View getDigit(T n, SizeType index, BaseType base) { + static constexpr View getDigit(T n, SizeType index, BaseType base) { if constexpr (minusCounted && std::is_same_v) if (n < 0 && index == 1) return '-'; - const DigitType intView = (n / std::pow(base, index)) % base; + do { + n /= base; + + index--; + } while (index > 0); if constexpr (std::is_integral_v) - return intView; + return n % base; else if constexpr (std::is_same_v) - return intView + '0'; + return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n % base]; else static_assert(alwaysFalse, "Unsupported view!"); } diff --git a/tests/src/main.cc b/tests/src/main.cc index 100ee32..6bc5840 100644 --- a/tests/src/main.cc +++ b/tests/src/main.cc @@ -1,2 +1,9 @@ #include +#include "ntl/impl/NumberDigitConvTraits.hh" + +namespace traits = ntl::impl::traits; + +TEST(NtlTests, hexTest) { + EXPECT_EQ(traits::NumberDigitConvTraits::getDigit(0xC, 0, 16), 'C'); +}