Skip to content

Commit

Permalink
Бета литералов
Browse files Browse the repository at this point in the history
  • Loading branch information
xiran56 committed Dec 23, 2023
1 parent f01d4a6 commit 9efdd38
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 24 deletions.
12 changes: 0 additions & 12 deletions README_EN.md

This file was deleted.

77 changes: 77 additions & 0 deletions include/ntl/impl/AsciiDigitTable.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#pragma once

#include <cstdint>
#include <type_traits>

namespace ntl {
namespace impl {
struct InvalidDigit : std::integral_constant<std::uint8_t, 36> {};

template<char ch>
struct AsciiDigitTable : std::integral_constant<std::uint8_t, InvalidDigit::value> {};

template<> struct AsciiDigitTable<'0'> : std::integral_constant<std::uint8_t, 0> {};
template<> struct AsciiDigitTable<'1'> : std::integral_constant<std::uint8_t, 1> {};
template<> struct AsciiDigitTable<'2'> : std::integral_constant<std::uint8_t, 2> {};
template<> struct AsciiDigitTable<'3'> : std::integral_constant<std::uint8_t, 3> {};
template<> struct AsciiDigitTable<'4'> : std::integral_constant<std::uint8_t, 4> {};
template<> struct AsciiDigitTable<'5'> : std::integral_constant<std::uint8_t, 5> {};
template<> struct AsciiDigitTable<'6'> : std::integral_constant<std::uint8_t, 6> {};
template<> struct AsciiDigitTable<'7'> : std::integral_constant<std::uint8_t, 7> {};
template<> struct AsciiDigitTable<'8'> : std::integral_constant<std::uint8_t, 8> {};
template<> struct AsciiDigitTable<'9'> : std::integral_constant<std::uint8_t, 9> {};
template<> struct AsciiDigitTable<'A'> : std::integral_constant<std::uint8_t, 10> {};
template<> struct AsciiDigitTable<'B'> : std::integral_constant<std::uint8_t, 11> {};
template<> struct AsciiDigitTable<'C'> : std::integral_constant<std::uint8_t, 12> {};
template<> struct AsciiDigitTable<'D'> : std::integral_constant<std::uint8_t, 13> {};
template<> struct AsciiDigitTable<'E'> : std::integral_constant<std::uint8_t, 14> {};
template<> struct AsciiDigitTable<'F'> : std::integral_constant<std::uint8_t, 15> {};
template<> struct AsciiDigitTable<'G'> : std::integral_constant<std::uint8_t, 16> {};
template<> struct AsciiDigitTable<'H'> : std::integral_constant<std::uint8_t, 17> {};
template<> struct AsciiDigitTable<'I'> : std::integral_constant<std::uint8_t, 18> {};
template<> struct AsciiDigitTable<'J'> : std::integral_constant<std::uint8_t, 19> {};
template<> struct AsciiDigitTable<'K'> : std::integral_constant<std::uint8_t, 20> {};
template<> struct AsciiDigitTable<'L'> : std::integral_constant<std::uint8_t, 21> {};
template<> struct AsciiDigitTable<'M'> : std::integral_constant<std::uint8_t, 22> {};
template<> struct AsciiDigitTable<'N'> : std::integral_constant<std::uint8_t, 23> {};
template<> struct AsciiDigitTable<'O'> : std::integral_constant<std::uint8_t, 24> {};
template<> struct AsciiDigitTable<'P'> : std::integral_constant<std::uint8_t, 25> {};
template<> struct AsciiDigitTable<'Q'> : std::integral_constant<std::uint8_t, 26> {};
template<> struct AsciiDigitTable<'R'> : std::integral_constant<std::uint8_t, 27> {};
template<> struct AsciiDigitTable<'S'> : std::integral_constant<std::uint8_t, 28> {};
template<> struct AsciiDigitTable<'T'> : std::integral_constant<std::uint8_t, 29> {};
template<> struct AsciiDigitTable<'U'> : std::integral_constant<std::uint8_t, 30> {};
template<> struct AsciiDigitTable<'V'> : std::integral_constant<std::uint8_t, 31> {};
template<> struct AsciiDigitTable<'W'> : std::integral_constant<std::uint8_t, 32> {};
template<> struct AsciiDigitTable<'X'> : std::integral_constant<std::uint8_t, 33> {};
template<> struct AsciiDigitTable<'Y'> : std::integral_constant<std::uint8_t, 34> {};
template<> struct AsciiDigitTable<'Z'> : std::integral_constant<std::uint8_t, 35> {};
template<> struct AsciiDigitTable<'a'> : std::integral_constant<std::uint8_t, 10> {};
template<> struct AsciiDigitTable<'b'> : std::integral_constant<std::uint8_t, 11> {};
template<> struct AsciiDigitTable<'c'> : std::integral_constant<std::uint8_t, 12> {};
template<> struct AsciiDigitTable<'d'> : std::integral_constant<std::uint8_t, 13> {};
template<> struct AsciiDigitTable<'e'> : std::integral_constant<std::uint8_t, 14> {};
template<> struct AsciiDigitTable<'f'> : std::integral_constant<std::uint8_t, 15> {};
template<> struct AsciiDigitTable<'g'> : std::integral_constant<std::uint8_t, 16> {};
template<> struct AsciiDigitTable<'h'> : std::integral_constant<std::uint8_t, 17> {};
template<> struct AsciiDigitTable<'i'> : std::integral_constant<std::uint8_t, 18> {};
template<> struct AsciiDigitTable<'j'> : std::integral_constant<std::uint8_t, 19> {};
template<> struct AsciiDigitTable<'k'> : std::integral_constant<std::uint8_t, 20> {};
template<> struct AsciiDigitTable<'l'> : std::integral_constant<std::uint8_t, 21> {};
template<> struct AsciiDigitTable<'m'> : std::integral_constant<std::uint8_t, 22> {};
template<> struct AsciiDigitTable<'n'> : std::integral_constant<std::uint8_t, 23> {};
template<> struct AsciiDigitTable<'o'> : std::integral_constant<std::uint8_t, 24> {};
template<> struct AsciiDigitTable<'p'> : std::integral_constant<std::uint8_t, 25> {};
template<> struct AsciiDigitTable<'q'> : std::integral_constant<std::uint8_t, 26> {};
template<> struct AsciiDigitTable<'r'> : std::integral_constant<std::uint8_t, 27> {};
template<> struct AsciiDigitTable<'s'> : std::integral_constant<std::uint8_t, 28> {};
template<> struct AsciiDigitTable<'t'> : std::integral_constant<std::uint8_t, 29> {};
template<> struct AsciiDigitTable<'u'> : std::integral_constant<std::uint8_t, 30> {};
template<> struct AsciiDigitTable<'v'> : std::integral_constant<std::uint8_t, 31> {};
template<> struct AsciiDigitTable<'w'> : std::integral_constant<std::uint8_t, 32> {};
template<> struct AsciiDigitTable<'x'> : std::integral_constant<std::uint8_t, 33> {};
template<> struct AsciiDigitTable<'y'> : std::integral_constant<std::uint8_t, 34> {};
template<> struct AsciiDigitTable<'z'> : std::integral_constant<std::uint8_t, 35> {};

}
}
24 changes: 24 additions & 0 deletions include/ntl/impl/CharConv.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <cstdint>
#include <type_traits>

#include "Helpers.hh"

namespace ntl::impl {
template<class Integer, std::uint8_t B>
constexpr auto toInt(const char *str) -> std::enable_if_t<std::is_integral_v<Integer>, Integer>
{
if (!str)
static_assert(alwaysFalse<Integer>, "Forwarded nullptr!");

Integer result { 0 };

while (*str) {
result *= B;

if constexpr (B <= 10)
if ('0' > str && str > ('0' + (B - 1)))
}
}
}
31 changes: 31 additions & 0 deletions include/ntl/impl/CharsToNumber.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "AsciiDigitTable.hh"
#include "Helpers.hh"
#include <cstdint>
#include <type_traits>

namespace ntl {
namespace impl {
template<class T, T, bool, std::uint8_t, char...>
struct CharsToNumber;

template<class T, T Prev, bool Negative, std::uint8_t Base, char First, char... Chars>
struct CharsToNumber<T, Prev, Negative, Base, First, Chars...>
: std::integral_constant<T, CharsToNumber<T,
(Prev * Base) + AsciiDigitTable<First>::value,
Negative, Base, Chars...>::value>
{ static_assert(AsciiDigitTable<First>::value != InvalidDigit::value && AsciiDigitTable<First>::value < Base, "Invalid digit!"); };

template<class T, T Prev, std::uint8_t Base, char... Chars>
struct CharsToNumber<T, Prev, false, Base, '-', Chars...>
: std::integral_constant<T, CharsToNumber<T, Prev, true, Base, Chars...>::value>
{ static_assert(Prev == 0, "\"-\" isn't in begin of number"); };

template<class T, T Prev, std::uint8_t Base>
struct CharsToNumber<T, Prev, false, Base> : std::integral_constant<T, Prev> { };

template<class T, T Prev, std::uint8_t Base>
struct CharsToNumber<T, Prev, true, Base> : std::integral_constant<T, -Prev> { };
}
}
21 changes: 14 additions & 7 deletions include/ntl/impl/Helpers.hh
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
#pragma once

namespace ntl::impl {
#include <type_traits>

namespace ntl {
template<class>
inline constexpr bool alwaysFalse { false };
struct AlwaysFalse : std::false_type {};

template<class T, T>
struct AlwaysFalseValue : std::false_type {};

class Traits {
public:
Traits() = delete;
~Traits() = delete;
};
namespace impl {
class Traits {
public:
Traits() = delete;
~Traits() = delete;
};
}
}
14 changes: 9 additions & 5 deletions include/ntl/impl/NumberDigitConvTraits.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -34,17 +34,21 @@ namespace ntl::impl::traits {
}

template<class View>
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<View, char>)
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<View>)
return intView;
return n % base;
else if constexpr (std::is_same_v<View, char>)
return intView + '0';
return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n % base];
else
static_assert(alwaysFalse<View>, "Unsupported view!");
}
Expand Down
7 changes: 7 additions & 0 deletions tests/src/main.cc
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
#include <gtest/gtest.h>

#include "ntl/impl/NumberDigitConvTraits.hh"

namespace traits = ntl::impl::traits;

TEST(NtlTests, hexTest) {
EXPECT_EQ(traits::NumberDigitConvTraits<int>::getDigit<char>(0xC, 0, 16), 'C');
}

0 comments on commit 9efdd38

Please sign in to comment.