Refactor and add tests for bits.hpp

pull/286/head
Michael 5 years ago
parent 4c4f3faf83
commit 6d8d910aff
No known key found for this signature in database
GPG Key ID: 2D51757B47E2434C

@ -658,6 +658,7 @@ set(TEST_SRC
test/test_llarp_router.cpp
test/util/test_llarp_util_aligned.cpp
test/util/test_llarp_util_bencode.cpp
test/util/test_llarp_util_bits.cpp
test/util/test_llarp_util_encode.cpp
test/util/test_llarp_util_ini.cpp
test/util/test_llarp_util_queue_manager.cpp
@ -765,7 +766,7 @@ else()
target_link_libraries(${STATIC_LIB} ${CRYPTOGRAPHY_LIB} ${LIBS} ${UTIL_LIB} ${PLATFORM_LIB})
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${UTIL_LIB} ${PLATFORM_LIB})
target_link_libraries(${TEST_EXE} ${STATIC_LINK_LIBS} gmock gtest ${STATIC_LIB} ${UTIL_LIB} ${PLATFORM_LIB})
target_link_libraries(${TEST_EXE} ${STATIC_LINK_LIBS} gmock gtest absl::variant ${STATIC_LIB} ${UTIL_LIB} ${PLATFORM_LIB})
if (WIN32)
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB} ${UTIL_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
target_link_libraries(${TEST_EXE} ${STATIC_LINK_LIBS} gmock gtest ${STATIC_LIB} ${UTIL_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)

@ -4,6 +4,7 @@
#include <net/exit_info.hpp>
#include <util/bencode.h>
#include <util/bits.hpp>
#include <util/mem.h>
#include <list>
@ -82,4 +83,23 @@ namespace llarp
return read;
}
std::ostream&
operator<<(std::ostream& out, const ExitInfo& xi)
{
char tmp[128] = {0};
if(inet_ntop(AF_INET6, (void*)&xi.address, tmp, sizeof(tmp)))
out << std::string(tmp);
else
return out;
out << std::string("/");
#if defined(ANDROID) || defined(RPI)
snprintf(tmp, sizeof(tmp), "%zu",
llarp::bits::count_array_bits(xi.netmask.s6_addr));
return out << tmp;
#else
return out << std::to_string(
llarp::bits::count_array_bits(xi.netmask.s6_addr));
#endif
}
} // namespace llarp

@ -4,9 +4,8 @@
#include <crypto/types.hpp>
#include <net/net.hpp>
#include <util/bencode.hpp>
#include <util/bits.hpp>
#include <iostream>
#include <iosfwd>
/**
* exit_info.h
@ -54,26 +53,10 @@ namespace llarp
ExitInfo &
operator=(const ExitInfo &other);
friend std::ostream &
operator<<(std::ostream &out, const ExitInfo &xi)
{
char tmp[128] = {0};
if(inet_ntop(AF_INET6, (void *)&xi.address, tmp, sizeof(tmp)))
out << std::string(tmp);
else
return out;
out << std::string("/");
#if defined(ANDROID) || defined(RPI)
snprintf(tmp, sizeof(tmp), "%zu",
llarp::bits::count_array_bits(xi.netmask.s6_addr));
return out << tmp;
#else
return out << std::to_string(
llarp::bits::count_array_bits(xi.netmask.s6_addr));
#endif
}
};
std::ostream &
operator<<(std::ostream &out, const ExitInfo &xi);
} // namespace llarp
#endif

@ -1,7 +1,10 @@
#ifndef LLARP_BITS_HPP
#define LLARP_BITS_HPP
#include <bitset>
#include <cstddef>
#include <numeric>
#include <type_traits>
namespace llarp
{
@ -9,27 +12,29 @@ namespace llarp
{
template < typename Int_t >
constexpr std::size_t
count_bits(const Int_t& i)
count_bits(Int_t i)
{
return i == 0 ? 0
: ((i & 0x01) == 0x01) ? 1UL + count_bits(i >> 1)
: count_bits(i >> 1);
static_assert(std::is_integral< Int_t >::value,
"Int_t should be an integer");
static_assert(std::is_unsigned< Int_t >::value,
"Int_t should be unsigned");
return std::bitset< std::numeric_limits< Int_t >::digits >(i).count();
}
template < typename T >
template < typename InputIt >
constexpr std::size_t
__count_array_bits(const T& array, std::size_t idx)
__count_array_bits(InputIt begin, InputIt end)
{
return idx < sizeof(T)
? count_bits(array[idx]) + __count_array_bits(array, idx + 1)
: 0;
return std::accumulate(begin, end, 0, [](auto acc, auto val) {
return acc + count_bits(val);
});
}
template < typename T >
constexpr std::size_t
count_array_bits(const T& array)
{
return __count_array_bits(array, 0);
return __count_array_bits(std::begin(array), std::end(array));
}
} // namespace bits
} // namespace llarp

@ -0,0 +1,66 @@
#include <gtest/gtest.h>
#include <array>
#include <absl/types/variant.h>
#include <util/bits.hpp>
using ArrayUC1 = std::array< unsigned char, 1 >;
using ArrayUC20 = std::array< unsigned char, 20 >;
using ArrayU1 = std::array< unsigned int, 1 >;
using ArrayULL1 = std::array< unsigned long long, 1 >;
using TestType = absl::variant< ArrayUC1, ArrayUC20, ArrayU1, ArrayULL1 >;
struct InputData
{
TestType data;
size_t result;
};
struct TestBits : public ::testing::TestWithParam< InputData >
{
};
TEST_P(TestBits, bitcount)
{
auto d = GetParam();
ASSERT_EQ(d.result,
absl::visit(
[](const auto& v) { return llarp::bits::count_array_bits(v); },
d.data));
}
// clang-format off
static const InputData inputData[] = {
{ArrayUC1{0b00000000}, 0},
{ArrayUC1{0b00000001}, 1},
{ArrayUC1{0b00000010}, 1},
{ArrayUC1{0b00000100}, 1},
{ArrayUC1{0b00001000}, 1},
{ArrayUC1{0b00010000}, 1},
{ArrayUC1{0b00100000}, 1},
{ArrayUC1{0b01000000}, 1},
{ArrayUC1{0b10000000}, 1},
{ArrayUC1{0b11111111}, 8},
{ArrayUC20{0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000}, 0},
{ArrayUC20{0b11111111, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b11111111, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b11111111, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b11111111, 0b00000100, 0b00000100, 0b00000100, 0b00000100}, 48},
{ArrayU1{0b00000000000000000000000000000000}, 0},
{ArrayU1{0b00101010101010101010101010101010}, 15},
{ArrayU1{0b10101010101010101010101010101010}, 16},
{ArrayU1{0b01010101010101010101010101010101}, 16},
{ArrayU1{0b11111111111111111111111111111111}, 32},
{ArrayULL1{0b0000000000000000000000000000000000000000000000000000000000000000}, 0},
{ArrayULL1{0b0010101010101010101010101010101000101010101010101010101010101010}, 30},
{ArrayULL1{0b1010101010101010101010101010101010101010101010101010101010101010}, 32},
{ArrayULL1{0b0101010101010101010101010101010101010101010101010101010101010101}, 32},
{ArrayULL1{0b1111111111111111111111111111111111111111111111111111111111111111}, 64},
};
// clang-format on
INSTANTIATE_TEST_CASE_P(TestBits, TestBits, ::testing::ValuesIn(inputData));
Loading…
Cancel
Save