Files
revng-revng/tests/unit/ADT.cpp
2025-02-13 13:10:51 +02:00

139 lines
4.5 KiB
C++

/// \file ADT.cpp
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#define BOOST_TEST_MODULE RegisterUsageAnalyses
bool init_unit_test();
#include "boost/test/unit_test.hpp"
#include "revng/ADT/CompilationTime.h"
#include "revng/ADT/Concepts.h"
#include "revng/ADT/ConstexprString.h"
#include "revng/ADT/STLExtras.h"
//
// CompilationTime.h
//
using namespace std::string_view_literals;
template<size_t Count>
consteval size_t fullSize(std::array<std::string_view, Count> Components,
std::string_view Separator) {
size_t Result = Separator.size() * Count;
compile_time::repeat<Count>([&Result, &Components]<size_t Index> {
Result += std::get<Index>(Components).size();
});
return Result;
}
inline constexpr std::array Components = { "instruction"sv,
"0x401000:Code_x86_64"sv,
"0x402000:Code_x86_64"sv,
"0x403000:Code_x86_64"sv };
static_assert(fullSize(Components, "/"sv) == 75);
//
// Concepts.h
//
static_assert(SpecializationOf<std::pair<int, long>, std::pair>);
static_assert(StrictSpecializationOf<std::pair<int, long>, std::pair>);
static_assert(SpecializationOf<const std::pair<int, long>, std::pair>);
static_assert(StrictSpecializationOf<const std::pair<int, long>, std::pair>);
static_assert(SpecializationOf<std::string, std::basic_string>);
static_assert(StrictSpecializationOf<std::string, std::basic_string>);
static_assert(not SpecializationOf<std::string, std::basic_string_view>);
static_assert(not StrictSpecializationOf<std::string, std::basic_string_view>);
using Alias = std::pair<int, long>;
static_assert(SpecializationOf<Alias, std::pair>);
static_assert(StrictSpecializationOf<Alias, std::pair>);
template<typename Type>
struct InheritanceT : std::pair<int, Type> {};
struct PublicInheritance : public InheritanceT<long> {};
struct PrivateInheritance : private InheritanceT<long> {};
struct ProtectedInheritance : protected InheritanceT<long> {};
static_assert(SpecializationOf<PublicInheritance, std::pair>);
static_assert(SpecializationOf<PublicInheritance, InheritanceT>);
static_assert(not SpecializationOf<PrivateInheritance, std::pair>);
static_assert(not SpecializationOf<ProtectedInheritance, std::pair>);
static_assert(not StrictSpecializationOf<PublicInheritance, std::pair>);
static_assert(not StrictSpecializationOf<PublicInheritance, InheritanceT>);
static_assert(not StrictSpecializationOf<PrivateInheritance, std::pair>);
static_assert(not StrictSpecializationOf<ProtectedInheritance, std::pair>);
//
// ConstexprString.h
//
template<ConstexprString String>
struct StringParametrizedTrait {
static constexpr std::string_view value = String;
};
static_assert(StringParametrizedTrait<"value">::value == "value");
BOOST_AUTO_TEST_CASE(ReachingDefinitionsTest) {
}
//
// STLExtras.h
//
consteval int takeAsTupleExample() {
std::array<int, 6> Data = { 42, 43, 44, 45, 46, 47 };
{
// Edit some elements.
auto &&[First, Second, Third] = takeAsTuple<3>(Data);
++First;
Second = 2;
Third = 3;
}
{
// Read multiple elements through a view.
auto &&[Second, Third] = takeAsTuple<2>(Data | std::views::drop(1));
return Second + Third;
}
}
static_assert(takeAsTupleExample() == 5);
constexpr bool test() {
constexpr std::array Input{ 1, 2, 3, 5, 7, 8, 10, 1 };
auto IsOdd = [](int I) { return I % 2 == 1; };
// The "copy" approach works fine for vectors
std::vector<int> InserterVectorOutput;
std::ranges::copy(Input | std::views::filter(IsOdd),
std::back_inserter(InserterVectorOutput));
// But it starts looking a lot uglier when applied to other containers.
// (using vector in this test because `std::set` only became `constexpr` in
// c++23, but the idea is the same: you cannot use `std::back_inserter` with
// sets).
using FakeSet = std::/* set */ vector<int>;
FakeSet InserterSetOutput;
std::ranges::copy(Input | std::views::filter(IsOdd),
std::inserter(InserterSetOutput,
InserterSetOutput.begin()));
// On the other hand, `revng::to` just works (tm) for everything that can be
// constructed from two iterators. And even looks nicer to boot.
FakeSet ToOutput = Input | std::views::filter(IsOdd) | revng::to<FakeSet>();
return ToOutput.size() == InserterVectorOutput.size()
&& InserterVectorOutput.size() == InserterSetOutput.size();
}
static_assert(test());