Skip to content

Commit

Permalink
Cleanup and reorganize. (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
GhostofCookie committed Sep 19, 2023
1 parent 7d09fc0 commit f46699f
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 237 deletions.
2 changes: 1 addition & 1 deletion benchmark/name.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <benchmark/benchmark.h>

#include <quicr_name>
#include <qname>
#include <vector>

static void Name_ConstructFrom_String(benchmark::State& state)
Expand Down
2 changes: 1 addition & 1 deletion benchmark/namespace.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <benchmark/benchmark.h>

#include <quicr_name>
#include <qname>
#include <vector>

static void Namespace_ConstructFrom_Name(benchmark::State& state)
Expand Down
File renamed without changes.
91 changes: 91 additions & 0 deletions include/quicr/_utilities.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#pragma once

#include <concepts>
#include <string>
#include <string_view>
#include <type_traits>

namespace quicr::utility
{

/**
* @brief Converts a hexadecimal character to it's decimal value.
*
* @tparam UInt_t The unsigned integer type to convert to.
* @param hex The hexadecimal character to convert.
* @returns The decimal value of the provided character.
*/
template<std::unsigned_integral UInt_t = std::uint64_t>
static constexpr UInt_t hexchar_to_unsigned(char hex) noexcept
{
if ('0' <= hex && hex <= '9')
return hex - '0';
else if ('A' <= hex && hex <= 'F')
return hex - 'A' + 10;
else if ('a' <= hex && hex <= 'f')
return hex - 'a' + 10;

return 0;
}

/**
* @brief Converts an unsigned integer decimal value into a hexidecimal
* character.
*
* @tparam UInt_t The unsigned integer type to convert from.
* @param value The decimal value to convert.
* @returns The hexadecimal character of the provided decimal value.
*/
template<std::unsigned_integral UInt_t>
static constexpr char unsigned_to_hexchar(UInt_t value) noexcept
{
if (value > 9) return value + 'A' - 10;
return value + '0';
}

/**
* @brief Converts a hexidecimal string to an unsigned integer decimal value.
*
* @tparam UInt_t The unsigned integer type to convert to.
* @param hex The hexadecimal string to convert from.
* @returns The decimal value of the provided hexadecimal string.
*/
template<std::unsigned_integral UInt_t>
static constexpr UInt_t hex_to_unsigned(std::string_view hex) noexcept
{
if (hex.starts_with("0x")) hex.remove_prefix(2);

UInt_t value = 0;
for (std::size_t i = 0; i < hex.length(); ++i)
{
value *= 16ull;
value += hexchar_to_unsigned<UInt_t>(hex[i]);
}

return value;
}

/**
* @brief Converts an unsigned integer to a hexadecimal string.
*
* @tparam UInt_t The unsigned integer type to convert from.
* @param value The decimal value to convert from.
* @returns The hexadecimal string of the provided decimal value.
*/
template<std::unsigned_integral UInt_t>
std::string unsigned_to_hex(UInt_t value) noexcept
{
char hex[sizeof(UInt_t) * 2 + 1] = "";
for (int i = sizeof(UInt_t) * 2 - 1; i >= 0; --i)
{
UInt_t b = value & 0x0F;
hex[i] = unsigned_to_hexchar(b);
value -= b;
value /= 16;
}
hex[sizeof(UInt_t) * 2] = '\0';

return hex;
}

}
23 changes: 12 additions & 11 deletions include/quicr/hex_endec.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#pragma once

#include <quicr/name.h>
#include "_utilities.h"
#include "name.h"

#include <algorithm>
#include <array>
#include <concepts>
#include <cstdint>
#include <numeric>
#include <span>
Expand All @@ -12,7 +14,6 @@

namespace quicr
{

/**
* @brief Encodes/Decodes a hex string from/into a list of unsigned integers
* values.
Expand Down Expand Up @@ -51,7 +52,7 @@ class HexEndec
* @returns Hex string containing the provided values distributed according
* to Dist in order.
*/
template<Unsigned... UInt_ts>
template<std::unsigned_integral... UInt_ts>
static inline std::string Encode(UInt_ts... values)
{
static_assert(Size == (Dist + ...), "Total bits cannot exceed specified size");
Expand All @@ -62,10 +63,10 @@ class HexEndec
return Encode(distribution, std::span<uint64_t>(vals));
}

template<Unsigned... UInt_ts>
template<std::unsigned_integral... UInt_ts>
static inline std::string Encode(std::span<uint16_t> distribution, UInt_ts... values)
{
if(Size < std::accumulate(distribution.begin(), distribution.end(), 0))
if (Size < std::accumulate(distribution.begin(), distribution.end(), 0))
throw std::invalid_argument("Total bits cannot exceed specified size");

std::array<uint64_t, sizeof...(UInt_ts)> vals{ values... };
Expand All @@ -88,7 +89,7 @@ class HexEndec

if constexpr (Size == sizeof(quicr::Name) * 8) return bits;

return "0x" + uint_to_hex(bits.bits<uint64_t>(0, Size));
return "0x" + utility::unsigned_to_hex(bits.bits<uint64_t>(0, Size));
}

/**
Expand All @@ -102,13 +103,13 @@ class HexEndec
* @returns Structured binding of values decoded from hex string
* corresponding in order to the size of Dist.
*/
template<Unsigned UInt_t = uint64_t>
template<std::unsigned_integral UInt_t = uint64_t>
static constexpr std::array<UInt_t, sizeof...(Dist)> Decode(std::string_view hex)
{
return Decode<UInt_t>(quicr::Name(hex));
}

template<Unsigned UInt_t = uint64_t>
template<std::unsigned_integral UInt_t = uint64_t>
static constexpr std::array<UInt_t, sizeof...(Dist)> Decode(quicr::Name name)
{
static_assert(Size >= (Dist + ...), "Total bits cannot exceed specified size");
Expand All @@ -117,7 +118,7 @@ class HexEndec
return Decode<sizeof...(Dist), UInt_t>(distribution, name);
}

template<size_t N, Unsigned UInt_t = uint64_t>
template<size_t N, std::unsigned_integral UInt_t = uint64_t>
static constexpr std::array<UInt_t, N> Decode(std::span<uint16_t> distribution, quicr::Name name)
{
const auto dist_size = distribution.size();
Expand All @@ -133,13 +134,13 @@ class HexEndec
return result;
}

template<Unsigned UInt_t = uint64_t>
template<std::unsigned_integral UInt_t = uint64_t>
static inline std::vector<UInt_t> Decode(std::span<uint16_t> distribution, std::string_view hex)
{
return Decode(distribution, quicr::Name(hex));
}

template<Unsigned UInt_t = uint64_t>
template<std::unsigned_integral UInt_t = uint64_t>
static inline std::vector<UInt_t> Decode(std::span<uint16_t> distribution, quicr::Name name)
{
const auto dist_size = distribution.size();
Expand Down
Loading

0 comments on commit f46699f

Please sign in to comment.