/// \file ZipMapIterator.cpp /// \brief Tests for ZipMapIterator // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include #include #define BOOST_TEST_MODULE ZipMapIterator bool init_unit_test(); #include "boost/test/unit_test.hpp" #include "revng/ADT/MutableSet.h" #include "revng/ADT/STLExtras.h" #include "revng/ADT/SmallMap.h" #include "revng/ADT/SortedVector.h" #include "revng/ADT/ZipMapIterator.h" #include "revng/UnitTestHelpers/UnitTestHelpers.h" // Local includes #include "TestKeyedObject.h" using namespace llvm; template struct KeyContainer {}; template struct KeyContainer { using key_type = typename T::key_type; static void insert(T &Container, typename T::key_type Key) { Container.insert({ Key, typename T::mapped_type() }); } static auto find(T &Container, typename T::key_type &Key) { return &*Container.find(Key); } static void sort(T &) {} }; template struct KeyContainer { using key_type = const typename T::key_type; static void insert(T &Container, key_type Key) { Container.insert(Key); } static auto find(T &Container, key_type Key) { return &*Container.find(Key); } static void sort(T &) {} }; template struct KeyContainer { using key_type = typename T::value_type::first_type; using value_type = std::conditional_t::value, const typename T::value_type, typename T::value_type>; using mapped_type = typename value_type::second_type; static void insert(T &Container, key_type Key) { Container.push_back({ Key, mapped_type() }); } static auto find(T &Container, key_type Key) { auto Condition = [Key](const value_type &Value) { return Value.first == Key; }; return &*std::find_if(Container.begin(), Container.end(), Condition); } static void sort(T &Container) { static_assert(not std::is_const::value, ""); using non_const_value_type = std::pair, mapped_type>; auto Less = [](const non_const_value_type &This, const non_const_value_type &Other) { return This.first < Other.first; }; using vector = std::vector; auto &NonConst = *reinterpret_cast(&Container); std::sort(NonConst.begin(), NonConst.end(), Less); } }; template static void compare(LeftType &Left, RightType &Right, std::vector, Optional>> &&Expected) { using LeftKE = KeyContainer; using RightKE = KeyContainer; using left_pointer = element_pointer_t; using right_pointer = element_pointer_t; std::vector> Result; std::copy(zipmap_begin(Left, Right), zipmap_end(Left, Right), std::back_inserter(Result)); revng_check(Result.size() == Expected.size()); auto FindLeft = [&Expected, &Left](unsigned I) { return Expected[I].first ? LeftKE::find(Left, *Expected[I].first) : nullptr; }; auto FindRight = [&Expected, &Right](unsigned I) { return Expected[I].second ? RightKE::find(Right, *Expected[I].second) : nullptr; }; for (unsigned I = 0; I < Result.size(); I++) { std::pair X{ FindLeft(I), FindRight(I) }; revng_check(Result[I] == X); } } template void run() { LeftMap A; RightMap B; LeftMap &ARef = A; RightMap &BRef = B; using LeftKC = KeyContainer; using RightKC = KeyContainer; LeftKC::insert(A, 1); LeftKC::insert(A, 2); LeftKC::insert(A, 4); LeftKC::insert(A, 5); LeftKC::sort(A); RightKC::insert(B, 1); RightKC::insert(B, 3); RightKC::insert(B, 4); RightKC::insert(B, 7); RightKC::sort(B); compare(ARef, BRef, { { { 1 }, { 1 } }, { { 2 }, {} }, { {}, { 3 } }, { { 4 }, { 4 } }, { { 5 }, {} }, { {}, { 7 } }, }); LeftKC::insert(A, 0); LeftKC::sort(A); compare(A, B, { { { 0 }, {} }, { { 1 }, { 1 } }, { { 2 }, {} }, { {}, { 3 } }, { { 4 }, { 4 } }, { { 5 }, {} }, { {}, { 7 } }, }); RightKC::insert(B, -1); RightKC::sort(B); compare(A, B, { { {}, { -1 } }, { { 0 }, {} }, { { 1 }, { 1 } }, { { 2 }, {} }, { {}, { 3 } }, { { 4 }, { 4 } }, { { 5 }, {} }, { {}, { 7 } }, }); } template void runSame() { run(); } BOOST_AUTO_TEST_CASE(TestStdMap) { runSame>(); } BOOST_AUTO_TEST_CASE(TestStdSet) { runSame>(); } BOOST_AUTO_TEST_CASE(TestMutableSet) { runSame>(); } BOOST_AUTO_TEST_CASE(TestSortedVector) { runSame>(); } BOOST_AUTO_TEST_CASE(TestStdVectorPair) { runSame>>(); } BOOST_AUTO_TEST_CASE(TestSmallMap) { runSame>(); } BOOST_AUTO_TEST_CASE(TestSortedVectorAndMutableSet) { run, MutableSet>(); }