Skip to content
Snippets Groups Projects
Commit a896f630 authored by Oskar Lappi's avatar Oskar Lappi Committed by Oskar Lappi
Browse files

Simple bimap consisting of two sets with a transparent comparator

parents
No related branches found
No related tags found
No related merge requests found
BasedOnStyle: LLVM
# General style settings
UseTab: Never
IndentWidth: 4
ContinuationIndentWidth: 2
ColumnLimit: 120
PenaltyBreakAssignment: 4000
# Comments
AlignTrailingComments: true
# Values
Cpp11BracedListStyle: true
# Declaration
AlignConsecutiveDeclarations: true
PointerAlignment: Right
# Assignment
AlignConsecutiveAssignments: true
SpaceBeforeAssignmentOperators: true
# Blocks
AllowShortBlocksOnASingleLine: Always
# Operations
SpaceAfterCStyleCast: false
AlignOperands: AlignAfterOperator
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeTernaryOperators: true
# Macros
IndentPPDirectives: AfterHash
AlignConsecutiveMacros: true
# Function signatures
AlwaysBreakAfterReturnType: AllDefinitions
AlwaysBreakTemplateDeclarations: Yes
AlignAfterOpenBracket: true
BreakBeforeBraces: WebKit
BinPackParameters: false
# Class signature
ConstructorInitializerIndentWidth: 2
BreakConstructorInitializers: BeforeColon
BreakBeforeBraces: WebKit
EmptyLineBeforeAccessModifier: Always
# Misc
AllowShortCaseLabelsOnASingleLine: true
build/
cmake_minimum_required(VERSION 3.16)
project(bimap CXX)
set(CMAKE_CXX_STANDARD 20)
add_library(bimap INTERFACE)
target_include_directories(bimap INTERFACE include)
include(cmake/fetch_catch2.cmake)
enable_testing()
add_subdirectory(samples)
add_subdirectory(test)
include(FetchContent)
set(FETCHCONTENT_QUIET FALSE)
FetchContent_Declare(
catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2
GIT_TAG devel
GIT_PROGRESS TRUE
OVERRIDE_FIND_PACKAGE
)
FetchContent_MakeAvailable(catch2)
#set(Catch2_DIR
#include <set>
#include <vector>
#include <utility>
#include <iterator>
#include <unordered_set>
template <typename T>
struct bimap_left {
T val;
};
template <typename T>
struct bimap_right {
T val;
};
template <typename L, typename R>
struct CompareBijection {
bool
operator()(const std::pair<L, R> &lhs, const std::pair<L, R> &rhs) const
{
return lhs.first < rhs.first;
}
bool
operator()(const bimap_left<L> &lhs, const std::pair<L, R> &rhs) const
{
return lhs.val < rhs.first;
}
bool
operator()(const bimap_right<R> &lhs, const std::pair<L, R> &rhs) const
{
return lhs.val < rhs.second;
}
bool
operator()(const std::pair<L, R> &lhs, const bimap_left<L> &rhs) const
{
return lhs.first < rhs.val;
}
bool
operator()(const std::pair<L, R> &lhs, const bimap_right<R> &rhs) const
{
return lhs.second < rhs.val;
}
using is_transparent = L;
};
template <typename L, typename R>
struct bijection {
using left = bimap_left<L>;
using right = bimap_right<R>;
using relation = std::pair<L,R>;
using relation_set = std::set<relation, CompareBijection<L,R>>;
using relation_iterator = typename relation_set::iterator;
std::set<L> left_elements;
std::set<R> right_elements;
relation_set relations;
// Insert relations
void
insert(L l, R r)
{
relations.insert({l,r});
}
void
insert(relation rel)
{
relations.insert(rel);
}
// Erase elements
void
erase(left l_key)
{
relations.erase(l_key);
}
void
erase(right r_key)
{
relations.erase(r_key);
}
void
l_erase(L l)
{
relations.erase(left{l});
}
void
r_erase(R r)
{
relations.erase(right{r});
}
// Contains
template <typename Key>
bool contains(Key key)
{
return relations.contains(key);
}
// Count
template <typename Key>
size_t
count(Key key)
{
return relations.count(key);
}
size_t
l_count(L l)
{
return count(left{l});
}
size_t
r_count(R r)
{
return count(right{r});
}
relation_iterator
find(left l_key){
return relations.find(l_key);
}
relation_iterator
find(right r_key){
return relations.find(l_key);
}
//TODO: add operator [] for both left and right access
R
at(left l_key){
auto r = relations.find(l_key);
return r->second;
}
L
at(right r_key){
auto r = relations.find(l_key);
return r->first;
}
};
#include <set>
#include <vector>
#include <utility>
#include <iterator>
#include <unordered_set>
template <typename T>
struct bimap_left {
T val;
};
template <typename T>
struct bimap_right {
T val;
};
template <typename L, typename R>
struct CompareLeft {
bool
operator()(const std::pair<L, R> &lhs, const std::pair<L, R> &rhs) const
{
return lhs.first < rhs.first || (lhs.first == rhs.first && lhs.second < rhs.second);
}
bool
operator()(const L &lhs, const std::pair<L, R> &rhs) const
{
return lhs < rhs.first;
}
bool
operator()(const std::pair<L, R> &lhs, const L &rhs) const
{
return lhs.first < rhs;
}
using is_transparent = L;
};
template <typename L, typename R>
struct CompareRight {
bool
operator()(const std::pair<L, R> &lhs, const std::pair<L, R> &rhs) const
{
return lhs.second < rhs.second || (lhs.second == rhs.second && lhs.first < rhs.first);
}
bool
operator()(const R &lhs, const std::pair<L, R> &rhs) const
{
return lhs < rhs.second;
}
bool
operator()(const std::pair<L, R> &lhs, const R &rhs) const
{
return lhs.second < rhs;
}
using is_transparent = L;
};
//TODO: maybe add unkeyed versions of member functions for when L != R
// (replacing left with L, right with R)
template <typename L, typename R>
struct bimap {
using left = bimap_left<L>;
using right = bimap_right<R>;
using relation = std::pair<L,R>;
using l_relation_set = std::set<relation, CompareLeft<L,R>>;
using r_relation_set = std::set<relation, CompareRight<L,R>>;
using relation_iterator = typename l_relation_set::iterator;
//TODO: see if the iterator types are the same
std::set<L> left_elements;
std::set<R> right_elements;
l_relation_set l_relations;
r_relation_set r_relations;
//TODO: badly named? Maybe should make the sets private if I have accessors...?
const l_relation_set&
relations_ref()
{
return l_relations;
}
std::vector<relation>
all_relations_vec()
{
std::vector<relation> rel;
for (auto it = l_relations.begin(); it != l_relations.end(); it++){
rel.push_back(*it);
}
return rel;
}
// Insert elements
void
insert(left l_key)
{
left_elements.insert(l_key.val);
}
void
insert(right r_key)
{
right_elements.insert(r_key.val);
}
void
l_insert(L l)
{
left_elements.insert(l);
}
void
r_insert(R r)
{
right_elements.insert(r);
}
// Insert relations
void
insert(L l, R r)
{
left_elements.insert(l);
right_elements.insert(r);
l_relations.insert({l,r});
r_relations.insert({l,r});
}
void
insert(relation rel)
{
left_elements.insert(rel.first);
right_elements.insert(rel.second);
l_relations.insert(rel);
r_relations.insert(rel);
}
// Erase relations
void
erase(const relation &rel)
{
r_relations.erase(rel);
l_relations.erase(rel);
}
// Erase elements
void
erase(left l_key)
{
left_elements.erase(l_key.val);
//Find all relations in l_relations and remove them from r_relations
auto &[lb, ub] = l_relations.equal_range(l_key.val);
for (auto it = lb; it < ub; it++){
r_relations.erase(*it);
}
l_relations.erase(l_key.val);
}
void
erase(right r_key)
{
right_elements.erase(r_key.val);
auto &[lb, ub] = r_relations.equal_range(r_key.val);
for (auto it = lb; it < ub; it++){
l_relations.erase(*it);
}
r_relations.erase(r_key.val);
}
void
l_erase(L l)
{
left_elements.erase(l);
auto &[lb, ub] = l_relations.equal_range(l);
for (auto it = lb; it < ub; it++){
r_relations.erase(*it);
}
l_relations.erase(l);
}
void
r_erase(R r)
{
right_elements.erase(r);
auto &[lb, ub] = l_relations.equal_range(r);
for (auto it = lb; it < ub; it++){
r_relations.erase(*it);
}
r_relations.erase(r);
}
// Contains
bool contains(relation rel)
{
return l_relations.contains(rel);
}
bool contains(left l_key)
{
return l_relations.contains(l_key.val);
}
bool contains(right r_key)
{
return r_relations.contains(r_key.val);
}
bool l_contains(L l)
{
return l_relations.contains(l);
}
bool r_contains(R r)
{
return r_relations.contains(r);
}
// Count
size_t
count(left l_key)
{
return l_relations.count(l_key.val);
}
size_t
count(right r_key)
{
return r_relations.count(r_key.val);
}
size_t
l_count(L l)
{
return l_relations.count(l);
}
size_t
r_count(R r)
{
return r_relations.count(r);
}
// Equal range
std::pair<relation_iterator, relation_iterator>
equal_range(left l_key)
{
return l_relations.equal_range(l_key.val);
}
std::pair<relation_iterator, relation_iterator>
equal_range(right r_key)
{
return r_relations.equal_range(r_key.val);
}
std::pair<relation_iterator, relation_iterator>
l_equal_range(L l)
{
return equal_range(left{l});
}
std::pair<relation_iterator, relation_iterator>
r_equal_range(R r)
{
return equal_range(right{r});
}
// Convenience function for getting a vector out
std::vector<R>
mapped_vector(left l_key)
{
std::vector<R> v;
auto [lb, ub] = equal_range(l_key);
v.reserve(std::distance(lb,ub));
for (auto it = lb; it != ub; it++){
v.push_back(it->second);
}
return v;
}
std::vector<L>
mapped_vector(right r_key)
{
std::vector<L> v;
auto [lb, ub] = equal_range(r_key);
v.reserve(std::distance(lb,ub));
for (auto it = lb; it != ub; it++){
v.push_back(it->first);
}
return v;
}
// Convenience function for getting a set
std::vector<R>
mapped_set(left l_key)
{
std::set<R> s;
auto [lb, ub] = equal_range(l_key);
for (auto it = lb; it != ub; it++){
s.insert(it->second);
}
return s;
}
std::vector<L>
mapped_set(right r_key)
{
std::set<L> s;
auto [lb, ub] = equal_range(r_key);
s.insert(ub - lb);
for (auto it = lb; it != ub; it++){
s.insert(it->first);
}
return s;
}
std::vector<R>
l_mapped_vector(L l)
{
return mapped_vector(left{l});
}
std::vector<L>
r_mapped_vector(R r)
{
return mapped_vector(right{r});
}
std::vector<R>
l_mapped_set(L l)
{
return mapped_set(left{l});
}
std::vector<L>
r_mapped_set(R r)
{
return mapped_set(right{r});
}
};
add_executable(int_double_bimap int_double_bimap.cpp)
target_link_libraries(int_double_bimap PRIVATE bimap)
add_executable(int_int_bimap int_int_bimap.cpp)
target_link_libraries(int_int_bimap PRIVATE bimap)
#include <cstdio>
#include <set>
#include <utility>
#include "bimap.hpp"
int
main(int argc, char* argv[])
{
(void)argc;
(void)argv;
bimap<int, double> bm;
bm.insert(1,1.0);
bm.insert(1,2.0);
bm.insert(2,1.0);
bm.insert(2,2.0);
bm.insert(2,3.0);
for (int i = 1; i < 3; i++){
printf("Key %d, %lu vals\n", i, bm.l_count(i));
const auto [lb, ub] = bm.l_equal_range(i);
for (auto it = lb; it != ub; it++){
printf(" %d : %lf\n", it->first, it->second);
}
//const auto [lb, ub] = bm.left_equal_range(i);
}
printf("\n");
for (int i = 1; i < 4; i++){
printf("Key %lf, %lu vals\n", (double)i, bm.r_count((double)i));
const auto [lb, ub] = bm.r_equal_range((double)i);
for (auto it = lb; it != ub; it++){
printf(" %d : %lf\n", it->first, it->second);
}
}
return 0;
}
#include <cstdio>
#include <set>
#include <utility>
#include "bimap.hpp"
bimap<int, int>
test_bimap1()
{
bimap<int, int> bm;
bm.insert(1,10);
bm.insert(1,12);
bm.insert(1,13);
bm.insert(2,20);
bm.insert(2,12);
bm.insert(2,23);
bm.insert(3,13);
bm.insert(3,23);
bm.l_insert(4);
return bm;
}
int
main(int argc, char* argv[])
{
(void)argc;
(void)argv;
auto bm = test_bimap1();
printf("All relations");
for (auto &rel : bm.l_relations){
printf(" %d : %d\n", rel.first, rel.second);
}
printf("\n");
for (auto &l : bm.left_elements){
printf("Key %d, %lu vals\n", l, bm.l_count(l));
const auto [lb, ub] = bm.l_equal_range(l);
for (auto it = lb; it != ub; it++){
printf(" %d : %d\n", it->first, it->second);
}
}
printf("\n");
for (auto &r : bm.right_elements){
printf("Key %d, %lu vals\n", r, bm.r_count(r));
const auto [lb, ub] = bm.r_equal_range(r);
for (auto it = lb; it != ub; it++){
printf(" %d : %d\n", it->first, it->second);
}
}
return 0;
}
include(cmake/TestSetup.cmake)
find_catch2_and_define_test_target()
include(Catch)
include(CTest)
add_subdirectory(bimap_api)
#add_subdirectory(bimap_binops)
#add_subdirectory(bimap_comparisons)
add_executable(bimap_test bimap_test.cpp)
target_link_libraries(bimap_test PRIVATE TestInterface)
catch_discover_tests(bimap_test)
#include "bimap.hpp"
#include <string>
#include <cstdint>
#include <vector>
#include <map>
#include <random>
#if defined(TESTS_CATCH2_USE_OLD_HEADER)
# include <catch2/catch.hpp>
#else
# include <catch2/catch_all.hpp>
#endif
TEST_CASE("Bimap basic type instances", "[bimap, instantiation]")
{
bimap<int, int> bm_ii;
bimap<int, double> bm_id;
bimap<double, float> bm_df;
bimap<std::string, float> bm_sf;
bimap<size_t, std::string> bm_us;
}
bimap<int, std::string>
test_bimap_int_string_1()
{
bimap<int, std::string> bm;
bm.insert(1,"1");
bm.insert(1,"12");
bm.insert(1,"13");
bm.insert(2,"2");
bm.insert(2,"12");
bm.insert(2,"23");
bm.insert(3,"13");
bm.insert(3,"23");
bm.l_insert(4);
bm.r_insert("100");
bm.r_insert("100");
return bm;
}
bimap<int, int>
test_bimap_int_int_1()
{
bimap<int, int> bm;
bm.insert(1,10);
bm.insert(1,12);
bm.insert(1,13);
bm.insert(2,20);
bm.insert(2,12);
bm.insert(2,23);
bm.insert(3,13);
bm.insert(3,23);
bm.l_insert(4);
return bm;
}
template <typename L, typename R>
void
test_counts(bimap<L,R> bm, std::map<L, size_t> l_counts, std::map<R, size_t> r_counts)
{
for (const auto &[l,count] : l_counts){
CHECK(bm.l_count(l) == count);
}
for (const auto &[r, count] : r_counts){
CHECK(bm.r_count(r) == count);
}
}
template <typename L, typename R>
void
ordered_bimap_mill(std::set<L> left_elems, std::set<R> right_elems)
{
bimap<L,R> bm;
std::map<L, size_t> l_counts;
std::map<R, size_t> r_counts;
//Insert all relations
for (const auto &l : left_elems){
for (const auto &r : right_elems){
bm.insert(l,r);
l_counts[l]++;
r_counts[r]++;
test_counts(bm, l_counts, r_counts);
}
}
// Check that every relation is counted for every element
for (const auto &l : left_elems){
CHECK(bm.l_count(l) == right_elems.size());
}
for (const auto &r : right_elems){
CHECK(bm.r_count(r) == left_elems.size());
}
test_counts(bm, l_counts, r_counts);
auto all_relations = bm.all_relations_vec();
for (const auto &rel : all_relations){
//Erase one relation at a time,
bm.erase(rel);
l_counts[rel.first]--;
r_counts[rel.second]--;
test_counts(bm, l_counts, r_counts);
}
}
template <typename L, typename R>
void
random_order_bimap_mill(std::set<L> left_elems, std::set<R> right_elems, size_t seed = 0)
{
std::mt19937 rng{seed};
bimap<L,R> bm;
std::map<L, size_t> l_counts;
std::map<R, size_t> r_counts;
//Insert all relations
for (const auto &l : left_elems){
for (const auto &r : right_elems){
bm.insert(l,r);
l_counts[l]++;
r_counts[r]++;
test_counts(bm, l_counts, r_counts);
}
}
// Check that every relation is counted for every element
for (const auto &l : left_elems){
CHECK(bm.l_count(l) == right_elems.size());
}
for (const auto &r : right_elems){
CHECK(bm.r_count(r) == left_elems.size());
}
test_counts(bm, l_counts, r_counts);
auto all_relations = bm.all_relations_vec();
for (size_t s = all_relations.size(); s > 0; s--){
size_t i = rng() % s;
auto rel = all_relations[i];
bm.erase(rel);
l_counts[rel.first]--;
r_counts[rel.second]--;
test_counts(bm, l_counts, r_counts);
all_relations.erase(all_relations.begin()+i);
}
}
TEST_CASE("Bimap insert", "[bimap, insert]")
{
bimap<int, int> bm = test_bimap_int_int_1();
bimap<int, std::string> bm2 = test_bimap_int_string_1();
}
// To test: bimap erase
// TODO: write a general test of consistency
// A set of conditions that must hold
TEST_CASE("Bimap count", "[bimap, count]")
{
{
bimap<int, int> bm = test_bimap_int_int_1();
using left = bimap<int, int>::left;
using right = bimap<int, int>::right;
CHECK(bm.count(left{1}) == 3);
CHECK(bm.count(left{2}) == 3);
CHECK(bm.count(left{3}) == 2);
CHECK(bm.count(left{4}) == 0);
CHECK(bm.count(left{5}) == 0);
CHECK(bm.count(right{10}) == 1);
CHECK(bm.count(right{12}) == 2);
CHECK(bm.count(right{13}) == 2);
CHECK(bm.count(right{20}) == 1);
CHECK(bm.count(right{23}) == 2);
}
{
bimap<int, std::string> bm = test_bimap_int_string_1();
using left = bimap<int, std::string>::left;
using right = bimap<int, std::string>::right;
CHECK(bm.count(left{1}) == 3);
CHECK(bm.count(left{2}) == 3);
CHECK(bm.count(left{3}) == 2);
CHECK(bm.count(left{4}) == 0);
CHECK(bm.count(left{5}) == 0);
CHECK(bm.count(right{"1"}) == 1);
CHECK(bm.count(right{"12"}) == 2);
CHECK(bm.count(right{"13"}) == 2);
CHECK(bm.count(right{"2"}) == 1);
CHECK(bm.count(right{"23"}) == 2);
CHECK(bm.count(right{"100"}) == 0);
}
}
TEST_CASE("Bimap left map view vectors", "[bimap, mapped_vector, left_view]")
{
bimap<int, int> bm = test_bimap_int_int_1();
using left = bimap<int, int>::left;
using right = bimap<int, int>::right;
auto v1 = bm.mapped_vector(left{1});
CHECK(v1.size() == 3);
CHECK(v1[0] == 10);
CHECK(v1[1] == 12);
CHECK(v1[2] == 13);
auto v2 = bm.mapped_vector(left{2});
CHECK(v2.size() == 3);
CHECK(v2[0] == 12);
CHECK(v2[1] == 20);
CHECK(v2[2] == 23);
auto v3 = bm.mapped_vector(left{3});
CHECK(v3.size() == 2);
CHECK(v3[0] == 13);
CHECK(v3[1] == 23);
auto v4 = bm.mapped_vector(left{4});
CHECK(v4.size() == 0);
auto v5 = bm.mapped_vector(left{5});
CHECK(v5.size() == 0);
/*
bimap<int, std::string> bm = test_bimap_int_int();
auto v1 = bm.mapped_vector(bimap_left_key(1));
CHECK(v1.size() == 3);
CHECK(v1[0] == 10);
CHECK(v1[1] == 12);
CHECK(v1[2] == 13);
auto v2 = bm.mapped_vector(bimap_left_key(2));
CHECK(v2.size() == 3);
CHECK(v2[0] == 12);
CHECK(v2[1] == 20);
CHECK(v2[2] == 23);
auto v3 = bm.mapped_vector(left{3});
CHECK(v3.size() == 2);
CHECK(v3[0] == 13);
CHECK(v3[1] == 23);
auto v4 = bm.mapped_vector(left{4});
CHECK(v4.size() == 0);
auto v5 = bm.mapped_vector(left{5});
CHECK(v5.size() == 0);
*/
}
TEST_CASE("Bimap right map view vectors", "[bimap, mapped_vector, right_view]")
{
bimap<int, int> bm = test_bimap_int_int_1();
using left = bimap<int, int>::left;
using right = bimap<int, int>::right;
auto v10 = bm.mapped_vector(right{10});
CHECK(v10.size() == 1);
CHECK(v10[0] == 1);
auto v12 = bm.mapped_vector(right{12});
CHECK(v12.size() == 2);
CHECK(v12[0] == 1);
CHECK(v12[1] == 2);
auto v13 = bm.mapped_vector(right{13});
CHECK(v13.size() == 2);
CHECK(v13[0] == 1);
CHECK(v13[1] == 3);
auto v20 = bm.mapped_vector(right{20});
CHECK(v20.size() == 1);
CHECK(v20[0] == 2);
auto v23 = bm.mapped_vector(right{23});
CHECK(v23.size() == 2);
CHECK(v23[0] == 2);
CHECK(v23[1] == 3);
auto v00 = bm.mapped_vector(right{0});
CHECK(v00.size() == 0);
}
//TODO: provide a generator for types that aren't convertible from size_t
template <typename L, typename R>
void
ordered_mill_linear_values(size_t n_left, size_t n_right)
{
std::set<L> lefts;
std::set<R> rights;
for (size_t i = 0; i < n_left; i++){
lefts.insert(L(i));
}
for (size_t i = 0; i < n_right; i++){
rights.insert(R(i));
}
ordered_bimap_mill(lefts, rights);
}
template <typename L, typename R>
void
ordered_mill_random_values(size_t n_left, size_t n_right, size_t seed = 0)
{
std::mt19937 rng{seed};
std::set<L> lefts;
std::set<R> rights;
for (size_t i = 0; i < n_left; i++){
size_t set_size = lefts.size();
while (set_size == lefts.size()){
lefts.insert(L(rng()));
}
}
for (size_t i = 0; i < n_right; i++){
size_t set_size = rights.size();
while (set_size == rights.size()){
rights.insert(R(rng()));
}
}
ordered_bimap_mill(lefts, rights);
}
template <typename L, typename R>
void
random_order_mill_linear_values(size_t n_left, size_t n_right)
{
std::set<L> lefts;
std::set<R> rights;
for (size_t i = 0; i < n_left; i++){
lefts.insert(L(i));
}
for (size_t i = 0; i < n_right; i++){
rights.insert(R(i));
}
random_order_bimap_mill(lefts, rights);
}
template <typename L, typename R>
void
random_order_mill_random_values(size_t n_left, size_t n_right, size_t seed = 0)
{
std::mt19937 rng{seed};
std::set<L> lefts;
std::set<R> rights;
for (size_t i = 0; i < n_left; i++){
size_t set_size = lefts.size();
while (set_size == lefts.size()){
lefts.insert(L(rng()));
}
}
for (size_t i = 0; i < n_right; i++){
size_t set_size = rights.size();
while (set_size == rights.size()){
rights.insert(R(rng()));
}
}
random_order_bimap_mill(lefts, rights);
}
size_t n_vals = 50;
TEST_CASE("Bimap<int, int> ordered mill of linear vals", "[bimap, insert, erase, count]")
{
ordered_mill_linear_values<int, int>(n_vals,n_vals);
}
TEST_CASE("Bimap<int, int> ordered mill of random vals", "[bimap, insert, erase, count]")
{
ordered_mill_random_values<int, int>(n_vals,n_vals, 313);
}
TEST_CASE("Bimap<int, int> random order mill of linear vals", "[bimap, insert, erase, count]")
{
random_order_mill_linear_values<int, int>(n_vals,n_vals);
}
TEST_CASE("Bimap<int, int> random order mill of random vals", "[bimap, insert, erase, count]")
{
random_order_mill_random_values<int, int>(n_vals,n_vals, 313);
}
//Strings
/*
TEST_CASE("Bimap<int, std::string> ordered mill of linear vals", "[bimap, insert, erase, count]")
{
ordered_mill_linear_values<int, int>(n_vals,n_vals);
}
TEST_CASE("Bimap<int, int> ordered mill of random vals", "[bimap, insert, erase, count]")
{
ordered_mill_random_values<int, int>(n_vals,n_vals, 313);
}
TEST_CASE("Bimap<int, int> random order mill of linear vals", "[bimap, insert, erase, count]")
{
random_order_mill_linear_values<int, int>(n_vals,n_vals);
}
TEST_CASE("Bimap<int, int> random order mill of random vals", "[bimap, insert, erase, count]")
{
random_order_mill_random_values<int, int>(n_vals,n_vals, 313);
}
*/
macro(find_catch2_and_define_test_target)
if (TARGET TestInterface)
set(TestInterface_EXISTS 1)
endif()
if(NOT Catch2_FOUND)
message("Loading Catch2 and defining test targets for ${CMAKE_CURRENT_LIST_DIR}")
find_package(Catch2 REQUIRED)
if(NOT TestInterface_EXISTS)
add_library(TestInterface INTERFACE)
endif()
if(Catch2_FOUND)
message(" found Catch2, version: ${Catch2_VERSION}")
if(NOT TARGET Catch2::Catch2WithMain)
message(SEND_ERROR
"Tests depend on Catch2::Catch2WithMain, but Catch2 was built without "
"it. To fix this, build Catch2 with CATCH_BUILD_STATIC_LIBRARY=ON\n"
"(see: https://github.com/catchorg/Catch2/releases/tag/v2.13.5)")
endif()
if(NOT TestInterface_EXISTS)
target_link_libraries(TestInterface INTERFACE ${PROJECT_NAME} Catch2::Catch2WithMain)
if(NOT ${Catch2_VERSION} VERSION_GREATER_EQUAL "3")
target_compile_definitions(TestInterface INTERFACE TESTS_CATCH2_USE_OLD_HEADER=1)
endif()
endif()
endif()
endif()
endmacro()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment