Final abseil purge

Bye-bye Google Boost.
pull/1124/head
Jason Rhinelander 4 years ago
parent 5ce6c01476
commit 0839c16f19

3
.gitmodules vendored

@ -1,9 +1,6 @@
[submodule "external/nlohmann"]
path = external/nlohmann
url = https://github.com/nlohmann/json.git
[submodule "external/abseil-cpp"]
path = external/abseil-cpp
url = https://github.com/abseil/abseil-cpp.git
[submodule "external/googletest"]
path = external/googletest
url = https://github.com/google/googletest.git

@ -249,7 +249,6 @@ if(SUBMODULE_CHECK)
endfunction ()
message(STATUS "Checking submodules")
check_submodule(external/abseil-cpp)
check_submodule(external/nlohmann)
check_submodule(external/googletest)
check_submodule(external/cxxopts)
@ -263,7 +262,6 @@ if(WITH_TESTS)
add_subdirectory(external/googletest EXCLUDE_FROM_ALL)
endif()
add_subdirectory(external/abseil-cpp EXCLUDE_FROM_ALL)
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(external/nlohmann EXCLUDE_FROM_ALL)
add_subdirectory(external/cxxopts)

@ -1 +0,0 @@
Subproject commit aa844899c937bde5d2b24f276b59997e5b668bde

@ -43,7 +43,6 @@ endif()
target_link_libraries(${UTIL_LIB} PUBLIC ${CRYPTOGRAPHY_LIB} ${LOG_LIB} ${CURL_LIBRARIES})
target_link_libraries(${UTIL_LIB} PUBLIC
absl::hash
nlohmann_json::nlohmann_json
ghc_filesystem
optional-lite

@ -161,7 +161,7 @@ namespace llarp
/// snode sessions we are talking to directly
SNodeSessions_t m_SNodeSessions;
std::unordered_map< huint128_t, PubKey, huint128_t::Hash > m_IPToKey;
std::unordered_map< huint128_t, PubKey > m_IPToKey;
huint128_t m_IfAddr;
huint128_t m_HigestAddr;
@ -169,8 +169,7 @@ namespace llarp
huint128_t m_NextAddr;
IPRange m_OurRange;
std::unordered_map< huint128_t, llarp_time_t, huint128_t::Hash >
m_IPActivity;
std::unordered_map< huint128_t, llarp_time_t > m_IPActivity;
llarp_tun_io m_Tun;

@ -215,8 +215,7 @@ namespace llarp
FlushSend();
/// maps ip to key (host byte order)
std::unordered_map< huint128_t, AlignedBuffer< 32 >, huint128_t::Hash >
m_IPToAddr;
std::unordered_map< huint128_t, AlignedBuffer< 32 > > m_IPToAddr;
/// maps key to ip (host byte order)
std::unordered_map< AlignedBuffer< 32 >, huint128_t,
AlignedBuffer< 32 >::Hash >
@ -289,8 +288,7 @@ namespace llarp
std::shared_ptr< dns::Proxy > m_Resolver;
/// maps ip address to timestamp last active
std::unordered_map< huint128_t, llarp_time_t, huint128_t::Hash >
m_IPActivity;
std::unordered_map< huint128_t, llarp_time_t > m_IPActivity;
/// our ip address (host byte order)
huint128_t m_OurIP;
/// next ip address to allocate (host byte order)

@ -1078,9 +1078,9 @@ namespace llarp
{
char buf[INET6_ADDRSTRLEN + 1] = {0};
std::string str;
in6_addr inaddr = {};
size_t numset = 0;
absl::uint128 bits = netmask_bits.h;
in6_addr inaddr = {};
size_t numset = 0;
uint128_t bits = netmask_bits.h;
while(bits)
{
if(bits & 1)

@ -1,7 +1,7 @@
#ifndef LLARP_NET_HPP
#define LLARP_NET_HPP
#include <absl/numeric/int128.h>
#include <net/uint128.h>
#include <net/address_info.hpp>
#include <net/net_int.hpp>
#include <net/net.h>

@ -39,7 +39,7 @@ namespace llarp
std::string
huint128_t::ToString() const
{
absl::uint128 addr = ntoh128(h);
auto addr = ntoh128(h);
char tmp[INET6_ADDRSTRLEN] = {0};
if(!inet_ntop(AF_INET6, (void*)&addr, tmp, sizeof(tmp)))
return "";
@ -61,7 +61,7 @@ namespace llarp
bool
huint128_t::FromString(const std::string& str)
{
absl::uint128 i;
llarp::uint128_t i;
if(!inet_pton(AF_INET6, str.c_str(), &i))
return false;
h = ntoh128(i);
@ -90,4 +90,4 @@ namespace llarp
{
return std::to_string(ntohs(n));
}
} // namespace llarp
} // namespace llarp

@ -19,8 +19,7 @@
#include <util/endian.hpp>
#include <vector>
#include <absl/numeric/int128.h>
#include <absl/hash/hash.h>
#include "uint128.h"
namespace llarp
{
@ -104,15 +103,6 @@ namespace llarp
return h == x.h;
}
using Hash = absl::Hash< huint_t< UInt_t > >;
template < typename H >
friend H
AbslHashValue(H hash, const huint_t< UInt_t >& i)
{
return H::combine(std::move(hash), i.h);
}
using V6Container = std::vector< uint8_t >;
void
ToV6(V6Container& c);
@ -132,7 +122,7 @@ namespace llarp
using huint32_t = huint_t< uint32_t >;
using huint16_t = huint_t< uint16_t >;
using huint128_t = huint_t< absl::uint128 >;
using huint128_t = huint_t< llarp::uint128_t >;
template < typename UInt_t >
struct nuint_t
@ -187,15 +177,6 @@ namespace llarp
return n == x.n;
}
struct Hash
{
inline size_t
operator()(nuint_t x) const
{
return std::hash< UInt_t >{}(x.n);
}
};
using V6Container = std::vector< uint8_t >;
void
ToV6(V6Container& c);
@ -212,7 +193,7 @@ namespace llarp
using nuint32_t = nuint_t< uint32_t >;
using nuint16_t = nuint_t< uint16_t >;
using nuint128_t = nuint_t< absl::uint128 >;
using nuint128_t = nuint_t< llarp::uint128_t >;
static inline nuint32_t
xhtonl(huint32_t x)
@ -239,4 +220,27 @@ namespace llarp
}
} // namespace llarp
namespace std
{
template < typename UInt_t >
struct hash< llarp::nuint_t< UInt_t > >
{
size_t
operator()(const llarp::nuint_t< UInt_t >& x) const
{
return std::hash< UInt_t >{}(x.n);
}
};
template < typename UInt_t >
struct hash< llarp::huint_t< UInt_t > >
{
size_t
operator()(const llarp::huint_t< UInt_t >& x) const
{
return std::hash< UInt_t >{}(x.h);
}
};
} // namespace std
#endif

@ -0,0 +1,267 @@
#pragma once
#include <array>
#include <cstdint>
#include <algorithm>
#include <functional>
#include "../util/meta/traits.hpp"
namespace llarp
{
/// 128-bit unsigned integer. Does *not* support
/// multiplication/division/modulus.
struct uint128_t
{
uint64_t lower, upper;
private:
template < typename BinaryOperator,
typename = traits::void_t< decltype(BinaryOperator{}(0, 0)) > >
constexpr uint128_t(const uint128_t& a, const uint128_t& b,
BinaryOperator op)
{
lower = op(a.lower, b.lower);
upper = op(a.upper, b.upper);
}
template < typename UnaryOperator,
typename = traits::void_t< decltype(UnaryOperator{}(0)) > >
constexpr uint128_t(const uint128_t& a, UnaryOperator op)
{
lower = op(a.lower);
upper = op(a.upper);
}
public:
// Initializes with 0s
constexpr uint128_t() : lower{0}, upper{0}
{
}
// Initializes with least-significant value
constexpr uint128_t(uint64_t lower) : lower{lower}, upper{0}
{
}
// Initializes with upper and lower values
constexpr uint128_t(uint64_t upper, uint64_t lower)
: lower{lower}, upper{upper}
{
}
constexpr uint128_t(const uint128_t&) = default;
constexpr uint128_t(uint128_t&&) = default;
constexpr uint128_t&
operator=(const uint128_t&) = default;
constexpr uint128_t&
operator=(uint128_t&&) = default;
constexpr uint128_t operator&(const uint128_t& o) const
{
return {*this, o, std::bit_and< uint64_t >{}};
}
/*
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value
&& std::is_unsigned<T>::value && sizeof(T) <= sizeof(uint64_t)>> constexpr T
operator&(T o) const
{
return lower & o;
}
*/
constexpr uint128_t
operator|(const uint128_t& o) const
{
return {*this, o, std::bit_or< uint64_t >{}};
}
constexpr uint128_t
operator^(const uint128_t& o) const
{
return {*this, o, std::bit_xor< uint64_t >{}};
}
constexpr uint128_t
operator~() const
{
return {*this, std::bit_not< uint64_t >{}};
}
explicit constexpr operator bool() const
{
return static_cast< bool >(lower) || static_cast< bool >(upper);
}
explicit constexpr operator uint8_t() const
{
return static_cast< uint8_t >(lower);
}
explicit constexpr operator uint16_t() const
{
return static_cast< uint16_t >(lower);
}
explicit constexpr operator uint32_t() const
{
return static_cast< uint32_t >(lower);
}
explicit constexpr operator uint64_t() const
{
return lower;
}
constexpr bool
operator==(const uint128_t& b) const
{
return lower == b.lower && upper == b.upper;
}
constexpr bool
operator!=(const uint128_t& b) const
{
return lower != b.lower || upper != b.upper;
}
constexpr bool
operator<(const uint128_t& b) const
{
return upper < b.upper || (upper == b.upper && lower < b.lower);
}
constexpr bool
operator<=(const uint128_t& b) const
{
return upper < b.upper || (upper == b.upper && lower <= b.lower);
}
constexpr bool
operator>(const uint128_t& b) const
{
return upper > b.upper || (upper == b.upper && lower > b.lower);
}
constexpr bool
operator>=(const uint128_t& b) const
{
return upper > b.upper || (upper == b.upper && lower >= b.lower);
}
constexpr uint128_t&
operator++()
{
if(++lower == 0)
++upper;
return *this;
}
constexpr uint128_t
operator++(int)
{
auto copy = *this;
++*this;
return copy;
}
constexpr uint128_t
operator+(const uint128_t& b) const
{
uint128_t sum{upper + b.upper, lower + b.lower};
if(sum.lower < lower)
++sum.upper;
return sum;
}
constexpr uint128_t
operator-(const uint128_t& b) const
{
uint128_t diff{upper - b.upper, lower - b.lower};
if(diff.lower > lower)
--diff.upper;
return diff;
}
constexpr uint128_t
operator<<(uint64_t shift) const
{
if(shift == 0)
return *this;
else if(shift < 64)
return {upper << shift | lower >> (64 - shift), lower << shift};
else if(shift == 64)
return {lower, 0};
else if(shift < 128)
return {lower << (shift - 64), 0};
else
return {0, 0};
}
constexpr uint128_t
operator>>(uint64_t shift) const
{
if(shift == 0)
return *this;
else if(shift < 64)
return {upper >> shift, lower >> shift | upper << (64 - shift)};
else if(shift == 64)
return {0, upper};
else if(shift < 128)
return {0, upper >> (shift - 64)};
else
return {0, 0};
}
constexpr uint128_t&
operator&=(const uint128_t& o)
{
return *this = *this & o;
}
constexpr uint128_t&
operator|=(const uint128_t& o)
{
return *this = *this | o;
}
constexpr uint128_t&
operator^=(const uint128_t& o)
{
return *this = *this ^ o;
}
constexpr uint128_t&
operator<<=(uint64_t shift)
{
return *this = *this << shift;
}
constexpr uint128_t&
operator>>=(uint64_t shift)
{
return *this = *this >> shift;
}
constexpr uint128_t&
operator+=(const uint128_t& b)
{
return *this = *this + b;
}
constexpr uint128_t&
operator-=(const uint128_t& b)
{
return *this = *this - b;
}
};
} // namespace llarp
namespace std
{
// Hash function for uint128_t
template <>
struct hash< llarp::uint128_t >
{
size_t
operator()(const llarp::uint128_t& i) const
{
size_t h = std::hash< uint64_t >()(i.lower);
h ^= std::hash< uint64_t >()(i.upper) + 0x9e3779b9 + (h << 6) + (h >> 2);
return h;
}
};
} // namespace std

@ -6,7 +6,7 @@
#include <numeric>
#include <type_traits>
#include <limits>
#include <absl/numeric/int128.h>
#include <net/uint128.h>
namespace llarp
{
@ -24,10 +24,9 @@ namespace llarp
}
constexpr std::size_t
count_bits_128(const absl::uint128& i)
count_bits_128(const uint128_t& i)
{
return count_bits(absl::Uint128High64(i))
+ count_bits(absl::Uint128Low64(i));
return count_bits(i.upper) + count_bits(i.lower);
}
template < typename InputIt >

@ -5,7 +5,7 @@
#include <cinttypes>
#include <cstring>
#include <absl/numeric/int128.h>
#include <net/uint128.h>
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/endian.h>
@ -200,15 +200,15 @@ htole64buf(void *buf, uint64_t big64)
htobuf64(buf, htole64(big64));
}
inline absl::uint128
ntoh128(absl::uint128 i)
inline llarp::uint128_t
ntoh128(llarp::uint128_t i)
{
#ifdef __BIG_ENDIAN__
return i;
#else
const auto loSwapped = htobe64(absl::Uint128Low64(i));
const auto hiSwapped = htobe64(absl::Uint128High64(i));
return absl::MakeUint128(loSwapped, hiSwapped);
const auto loSwapped = htobe64(i.lower);
const auto hiSwapped = htobe64(i.upper);
return {loSwapped, hiSwapped};
#endif
}

@ -35,10 +35,8 @@ list(APPEND GTEST_SRC
util/meta/test_llarp_util_traits.cpp
util/test_llarp_util_aligned.cpp
util/test_llarp_util_bencode.cpp
util/test_llarp_util_bits.cpp
util/test_llarp_util_decaying_hashset.cpp
util/test_llarp_util_encode.cpp
util/test_llarp_util_printer.cpp
util/test_llarp_util_log_level.cpp
util/thread/test_llarp_util_queue_manager.cpp
util/thread/test_llarp_util_queue.cpp
@ -58,12 +56,10 @@ add_executable(${GTEST_EXE}
target_link_libraries(${GTEST_EXE} PUBLIC gmock gtest ${STATIC_LIB})
target_include_directories(${GTEST_EXE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
if(NOT WIN32)
target_link_libraries(${GTEST_EXE} PUBLIC absl::variant)
else()
if(WIN32)
target_sources(${GTEST_EXE} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/win32/test.rc")
target_link_libraries(${GTEST_EXE} PUBLIC ws2_32 iphlpapi shlwapi)
endif(NOT WIN32)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
target_link_directories(${GTEST_EXE} PRIVATE /usr/local/lib)
@ -74,6 +70,8 @@ add_subdirectory(Catch2)
add_executable(${CATCH_EXE}
nodedb/test_nodedb.cpp
path/test_path.cpp
util/test_llarp_util_bits.cpp
util/test_llarp_util_printer.cpp
util/test_llarp_util_str.cpp
check_main.cpp)

@ -87,12 +87,12 @@ struct ClientHandler : public abyss::http::IRPCClientHandler
}
void
PopulateReqHeaders(ABSL_ATTRIBUTE_UNUSED abyss::http::Headers_t& hdr)
PopulateReqHeaders(abyss::http::Headers_t& /*hdr*/)
{
}
bool
HandleResponse(ABSL_ATTRIBUTE_UNUSED abyss::http::RPC_Response response)
HandleResponse(abyss::http::RPC_Response /*response*/)
{
test->AsyncStop();
return true;
@ -108,7 +108,7 @@ struct ServerHandler : public abyss::httpd::IRPCHandler
}
Response
HandleJSONRPC(Method_t method, ABSL_ATTRIBUTE_UNUSED const Params& params)
HandleJSONRPC(Method_t method, const Params& /*params*/)
{
test->AssertMethod(method);
test->called = true;

@ -1,66 +1,59 @@
#include <gtest/gtest.h>
#include <array>
#include <absl/types/variant.h>
#include <catch2/catch.hpp>
#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 >;
TEST_CASE("test bit counting, 8-bit", "[bits]") {
auto x = GENERATE(table<std::array<unsigned char, 1>, size_t>({
{{{0b00000000}}, 0},
{{{0b00000001}}, 1},
{{{0b00000010}}, 1},
{{{0b00000100}}, 1},
{{{0b00001000}}, 1},
{{{0b00010000}}, 1},
{{{0b00100000}}, 1},
{{{0b01000000}}, 1},
{{{0b10000000}}, 1},
{{{0b11111111}}, 8},
}));
REQUIRE( llarp::bits::count_array_bits(std::get<0>(x)) == std::get<1>(x) );
}
struct InputData
{
TestType data;
size_t result;
};
TEST_CASE("test bit counting, 20 x 8-bit", "[bits]") {
auto x = GENERATE(table<std::array<unsigned char, 20>, size_t>({
{{{0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000}},
0},
{{{0b11111111, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b11111111, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b11111111, 0b00000100, 0b00000100, 0b00000100, 0b00000100,
0b11111111, 0b00000100, 0b00000100, 0b00000100, 0b00000100}},
48},
}));
REQUIRE( llarp::bits::count_array_bits(std::get<0>(x)) == std::get<1>(x) );
}
struct TestBits : public ::testing::TestWithParam< InputData >
{
};
TEST_CASE("test bit counting, unsigned int", "[bits]") {
auto x = GENERATE(table<std::array<unsigned int, 1>, size_t>({
{{{0b00000000000000000000000000000000}}, 0},
{{{0b00101010101010101010101010101010}}, 15},
{{{0b10101010101010101010101010101010}}, 16},
{{{0b01010101010101010101010101010101}}, 16},
{{{0b11111111111111111111111111111111}}, 32},
}));
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));
REQUIRE( llarp::bits::count_array_bits(std::get<0>(x)) == std::get<1>(x) );
}
// 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
TEST_CASE("test bit counting, unsigned long long", "[bits]") {
auto x = GENERATE(table<std::array<unsigned long long, 1>, size_t>({
{{{0b0000000000000000000000000000000000000000000000000000000000000000}}, 0},
{{{0b0010101010101010101010101010101000101010101010101010101010101010}}, 30},
{{{0b1010101010101010101010101010101010101010101010101010101010101010}}, 32},
{{{0b0101010101010101010101010101010101010101010101010101010101010101}}, 32},
{{{0b1111111111111111111111111111111111111111111111111111111111111111}}, 64},
}));
INSTANTIATE_TEST_SUITE_P(TestBits, TestBits, ::testing::ValuesIn(inputData));
REQUIRE( llarp::bits::count_array_bits(std::get<0>(x)) == std::get<1>(x) );
}

@ -1,13 +1,9 @@
#include <util/printer.hpp>
#include <absl/types/variant.h>
#include <unordered_map>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <catch2/catch.hpp>
#include <sstream>
#include <map>
using namespace llarp;
using namespace ::testing;
struct PrintableType
{
@ -19,127 +15,80 @@ struct PrintableType
}
};
using SingleVariant =
absl::variant< char, bool, short, int, unsigned int, const void *,
const char *, std::string, const int *,
std::pair< int, std::string >,
std::tuple< int, std::string, int >,
std::map< std::string, char >, PrintableType >;
using SingleType = std::pair< SingleVariant, Matcher< std::string > >;
class SingleValueTest : public ::testing::TestWithParam< SingleType >
{
};
TEST_P(SingleValueTest, value)
{
SingleType d = GetParam();
std::ostringstream stream;
template <typename T>
std::string print(const T &x) {
std::ostringstream os;
{
Printer printer(stream, -1, -1);
absl::visit([&](const auto &x) { printer.printValue(x); }, d.first);
Printer printer(os, -1, -1);
printer.printValue(x);
}
ASSERT_THAT(stream.str(), d.second);
return os.str();
}
static const char PTR_TYPE[] = "abacus";
static const int INT_VAL = 100;
// clang-format off
static const SingleType singleType[] = {
{char('a'), StrEq("[ 'a' ]")},
{bool(true), StrEq("[ true ]")},
{bool(false), StrEq("[ false ]")},
{short(123), StrEq("[ 123 ]")},
{int(INT_MAX - 1), StrEq("[ 2147483646 ]")},
{static_cast< unsigned int >(std::numeric_limits< int >::max()) + 1, StrEq("[ 2147483648 ]")},
{static_cast< const void * >(PTR_TYPE), AllOf(StartsWith("[ 0x"), EndsWith(" ]"))},
{static_cast< const char * >(PTR_TYPE), StrEq("[ \"abacus\" ]")},
{std::string("abacus"), StrEq("[ \"abacus\" ]")},
{static_cast< const int * >(&INT_VAL), AllOf(StartsWith("[ 0x"), EndsWith(" ]"))},
{std::pair< int, std::string >(100, "abacus"), StrEq("[ [ 100 \"abacus\" ] ]")},
{std::tuple< int, std::string, int >(100, "abacus", 123), StrEq("[ [ 100 \"abacus\" 123 ] ]")},
{std::map< std::string, char >{{"one", 'a'}, {"two", 'b'}, {"three", 'c'}}, StrEq("[ [ [ \"one\" \'a\' ] [ \"three\" \'c\' ] [ \"two\" 'b' ] ] ]")},
{PrintableType(), StrEq("[ PrintableType -2 -1 ]")},
TEST_CASE("printable types", "[printer]") {
REQUIRE( print(char('a')) == "[ 'a' ]" );
REQUIRE( print(bool(true)) == "[ true ]" );
REQUIRE( print(bool(false)) == "[ false ]" );
REQUIRE( print(short(123)) == "[ 123 ]" );
REQUIRE( print(int(std::numeric_limits<int>::max() - 1)) == "[ 2147483646 ]" );
REQUIRE( print(static_cast< unsigned int >(std::numeric_limits< int >::max()) + 1) == "[ 2147483648 ]" );
using Catch::Matchers::StartsWith;
using Catch::Matchers::EndsWith;
static const char PTR_TYPE[] = "abacus";
REQUIRE_THAT( print(static_cast< const void * >(PTR_TYPE)), StartsWith("[ 0x") && EndsWith(" ]") );
REQUIRE( print(static_cast< const char * >(PTR_TYPE)) == R"([ "abacus" ])" );
REQUIRE( print(std::string("abacus")) == R"([ "abacus" ])" );
static const int INT_VAL = 100;
REQUIRE_THAT( print(static_cast< const int * >(&INT_VAL)), StartsWith("[ 0x") && EndsWith(" ]") );
REQUIRE( print(std::pair< int, std::string >(100, "abacus")) == R"([ [ 100 "abacus" ] ])" );
REQUIRE( print(std::tuple< int, std::string, int >(100, "abacus", 123)) == R"([ [ 100 "abacus" 123 ] ])" );
REQUIRE( print(std::map< std::string, char >{{"one", 'a'}, {"two", 'b'}, {"three", 'c'}})
== R"([ [ [ "one" 'a' ] [ "three" 'c' ] [ "two" 'b' ] ] ])" );
REQUIRE( print(PrintableType()) == "[ PrintableType -2 -1 ]" );
};
// clang-format on
INSTANTIATE_TEST_SUITE_P(Printer, SingleValueTest,
::testing::ValuesIn(singleType));
using SingleAttributeType =
std::tuple< std::string, SingleVariant, Matcher< std::string > >;
class SingleAttributeTest
: public ::testing::TestWithParam< SingleAttributeType >
{
};
TEST_P(SingleAttributeTest, value)
{
SingleAttributeType d = GetParam();
std::ostringstream stream;
template <typename T>
std::string printAttribute(const std::string& attr, const T &x) {
std::ostringstream os;
{
Printer printer(stream, -1, -1);
absl::visit(
[&](const auto &x) { printer.printAttribute(std::get< 0 >(d), x); },
std::get< 1 >(d));
Printer printer(os, -1, -1);
printer.printAttribute(attr, x);
}
ASSERT_THAT(stream.str(), std::get< 2 >(d));
return os.str();
}
// clang-format off
static const SingleAttributeType singleAttributeType[] = {
SingleAttributeType("our_value", char('a'), StrEq("[ our_value = 'a' ]")),
SingleAttributeType("our_value", bool(true), StrEq("[ our_value = true ]")),
SingleAttributeType("our_value", bool(false), StrEq("[ our_value = false ]")),
SingleAttributeType("our_value", short(123), StrEq("[ our_value = 123 ]")),
SingleAttributeType("our_value", int(INT_MAX - 1), StrEq("[ our_value = 2147483646 ]")),
SingleAttributeType("our_value", static_cast< unsigned int >(std::numeric_limits< int >::max()) + 1, StrEq("[ our_value = 2147483648 ]")),
SingleAttributeType("our_value", static_cast< const void * >(PTR_TYPE), AllOf(StartsWith("[ our_value = 0x"), EndsWith(" ]"))),
SingleAttributeType("our_value", static_cast< const char * >(PTR_TYPE), StrEq("[ our_value = \"abacus\" ]")),
SingleAttributeType("our_value", std::string("abacus"), StrEq("[ our_value = \"abacus\" ]")),
SingleAttributeType("our_value", static_cast< const int * >(&INT_VAL), AllOf(StartsWith("[ our_value = 0x"), EndsWith(" ]"))),
SingleAttributeType("our_value", std::pair< int, std::string >(100, "abacus"), StrEq("[ our_value = [ 100 \"abacus\" ] ]")),
SingleAttributeType("our_value", std::tuple< int, std::string, int >(100, "abacus", 123), StrEq("[ our_value = [ 100 \"abacus\" 123 ] ]")),
SingleAttributeType("our_value", std::map< std::string, char >{{"one", 'a'}, {"two", 'b'}, {"three", 'c'}}, StrEq("[ our_value = [ [ \"one\" \'a\' ] [ \"three\" \'c\' ] [ \"two\" 'b' ] ] ]")),
SingleAttributeType("our_value", PrintableType(), StrEq("[ our_value = PrintableType -2 -1 ]")),
};
// clang-format on
INSTANTIATE_TEST_SUITE_P(Printer, SingleAttributeTest,
::testing::ValuesIn(singleAttributeType));
TEST_CASE("printable types, with attribute", "[printer]") {
REQUIRE( printAttribute("fee", char('a')) == "[ fee = 'a' ]" );
REQUIRE( printAttribute("fi", int(32)) == "[ fi = 32 ]" );
REQUIRE( printAttribute("fo", std::map< std::string, char >{{"one", 'a'}, {"two", 'b'}, {"three", 'c'}})
== R"([ fo = [ [ "one" 'a' ] [ "three" 'c' ] [ "two" 'b' ] ] ])" );
REQUIRE( printAttribute("fum", PrintableType()) == "[ fum = PrintableType -2 -1 ]");
}
using ManyAttributes =
std::pair< std::vector< std::pair< std::string, SingleVariant > >,
Matcher< std::string > >;
void printAnother(Printer &) {}
class ManyAttributesTest : public ::testing::TestWithParam< ManyAttributes >
{
};
template <typename T, typename... Tmore>
void printAnother(Printer &p, const std::string &attr, const T& x, const Tmore&... more) {
p.printAttribute(attr, x);
printAnother(p, more...);
}
TEST_P(ManyAttributesTest, value)
{
ManyAttributes d = GetParam();
std::ostringstream stream;
template <typename... T>
std::string printMany(const T&... x) {
std::ostringstream os;
{
Printer printer(stream, -1, -1);
std::for_each(d.first.begin(), d.first.end(), [&](const auto &y) {
std::string n = y.first;
const auto &v = y.second;
absl::visit([&](const auto &x) { printer.printAttribute(n, x); }, v);
});
Printer p(os, -1, -1);
printAnother(p, x...);
}
ASSERT_THAT(stream.str(), d.second);
return os.str();
}
// clang-format off
static const ManyAttributes manyAttributes[] = {
{{{"val", 1}, {"v2", 2}, {"v3", 3}, {"str", std::string("xxx")}}, StrEq("[ val = 1 v2 = 2 v3 = 3 str = \"xxx\" ]")},
{{{"str", std::string("xxx")}}, StrEq("[ str = \"xxx\" ]")}
};
// clang-format on
TEST_CASE("printable types, with multiple attributes", "[printer]") {
REQUIRE( printMany("val", 1, "v2", 2, "v3", 3, "str", std::string{"xxx"})
== "[ val = 1 v2 = 2 v3 = 3 str = \"xxx\" ]" );
REQUIRE( printMany("str", std::string{"xxx"}) == "[ str = \"xxx\" ]" );
}
INSTANTIATE_TEST_SUITE_P(Printer, ManyAttributesTest,
::testing::ValuesIn(manyAttributes));

Loading…
Cancel
Save