mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-06 14:38:17 +01:00
externals: Add robin-map
Merge commit '8bf66a678a' as 'externals/robin-map'
This commit is contained in:
commit
91578edc69
20 changed files with 8234 additions and 0 deletions
25
externals/robin-map/tests/CMakeLists.txt
vendored
Normal file
25
externals/robin-map/tests/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
project(tsl_robin_map_tests)
|
||||
|
||||
add_executable(tsl_robin_map_tests "main.cpp"
|
||||
"custom_allocator_tests.cpp"
|
||||
"policy_tests.cpp"
|
||||
"robin_map_tests.cpp"
|
||||
"robin_set_tests.cpp")
|
||||
|
||||
target_compile_features(tsl_robin_map_tests PRIVATE cxx_std_11)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
target_compile_options(tsl_robin_map_tests PRIVATE -Werror -Wall -Wextra -Wold-style-cast -DTSL_DEBUG -UNDEBUG)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
target_compile_options(tsl_robin_map_tests PRIVATE /bigobj /WX /W3 /DTSL_DEBUG /UNDEBUG)
|
||||
endif()
|
||||
|
||||
# Boost::unit_test_framework
|
||||
find_package(Boost 1.54.0 REQUIRED COMPONENTS unit_test_framework)
|
||||
target_link_libraries(tsl_robin_map_tests PRIVATE Boost::unit_test_framework)
|
||||
|
||||
# tsl::robin_map
|
||||
add_subdirectory(../ ${CMAKE_CURRENT_BINARY_DIR}/tsl)
|
||||
target_link_libraries(tsl_robin_map_tests PRIVATE tsl::robin_map)
|
||||
150
externals/robin-map/tests/custom_allocator_tests.cpp
vendored
Normal file
150
externals/robin-map/tests/custom_allocator_tests.cpp
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#define BOOST_TEST_DYN_LINK
|
||||
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <tsl/robin_map.h>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
static std::size_t nb_custom_allocs = 0;
|
||||
|
||||
template<typename T>
|
||||
class custom_allocator {
|
||||
public:
|
||||
using value_type = T;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using propagate_on_container_move_assignment = std::true_type;
|
||||
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
using other = custom_allocator<U>;
|
||||
};
|
||||
|
||||
custom_allocator() = default;
|
||||
custom_allocator(const custom_allocator&) = default;
|
||||
|
||||
template<typename U>
|
||||
custom_allocator(const custom_allocator<U>&) {
|
||||
}
|
||||
|
||||
pointer address(reference x) const noexcept {
|
||||
return &x;
|
||||
}
|
||||
|
||||
const_pointer address(const_reference x) const noexcept {
|
||||
return &x;
|
||||
}
|
||||
|
||||
pointer allocate(size_type n, const void* /*hint*/ = 0) {
|
||||
nb_custom_allocs++;
|
||||
|
||||
pointer ptr = static_cast<pointer>(std::malloc(n * sizeof(T)));
|
||||
if(ptr == nullptr) {
|
||||
#ifdef TSL_RH_NO_EXCEPTIONS
|
||||
std::abort();
|
||||
#else
|
||||
throw std::bad_alloc();
|
||||
#endif
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void deallocate(T* p, size_type /*n*/) {
|
||||
std::free(p);
|
||||
}
|
||||
|
||||
size_type max_size() const noexcept {
|
||||
return std::numeric_limits<size_type>::max()/sizeof(value_type);
|
||||
}
|
||||
|
||||
template<typename U, typename... Args>
|
||||
void construct(U* p, Args&&... args) {
|
||||
::new(static_cast<void *>(p)) U(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
void destroy(U* p) {
|
||||
p->~U();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
bool operator==(const custom_allocator<T>&, const custom_allocator<U>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator!=(const custom_allocator<T>&, const custom_allocator<U>&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO Avoid overloading new to check number of global new
|
||||
// static std::size_t nb_global_new = 0;
|
||||
// void* operator new(std::size_t sz) {
|
||||
// nb_global_new++;
|
||||
// return std::malloc(sz);
|
||||
// }
|
||||
//
|
||||
// void operator delete(void* ptr) noexcept {
|
||||
// std::free(ptr);
|
||||
// }
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(test_custom_allocator)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_custom_allocator_1) {
|
||||
// nb_global_new = 0;
|
||||
nb_custom_allocs = 0;
|
||||
|
||||
tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
|
||||
custom_allocator<std::pair<int, int>>> map;
|
||||
|
||||
const int nb_elements = 1000;
|
||||
for(int i = 0; i < nb_elements; i++) {
|
||||
map.insert({i, i*2});
|
||||
}
|
||||
|
||||
BOOST_CHECK_NE(nb_custom_allocs, 0);
|
||||
// BOOST_CHECK_EQUAL(nb_global_new, 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
28
externals/robin-map/tests/main.cpp
vendored
Normal file
28
externals/robin-map/tests/main.cpp
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#define BOOST_TEST_MODULE robin_map_tests
|
||||
#define BOOST_TEST_DYN_LINK
|
||||
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
102
externals/robin-map/tests/policy_tests.cpp
vendored
Normal file
102
externals/robin-map/tests/policy_tests.cpp
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#define BOOST_TEST_DYN_LINK
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <ratio>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <tsl/robin_growth_policy.h>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(test_policy)
|
||||
|
||||
using test_types = boost::mpl::list<tsl::rh::power_of_two_growth_policy<2>,
|
||||
tsl::rh::power_of_two_growth_policy<4>,
|
||||
tsl::rh::prime_growth_policy,
|
||||
tsl::rh::mod_growth_policy<>,
|
||||
tsl::rh::mod_growth_policy<std::ratio<7,2>>>;
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test_policy, Policy, test_types) {
|
||||
// Call next_bucket_count() on the policy until we reach its max_bucket_count()
|
||||
std::size_t bucket_count = 0;
|
||||
Policy policy(bucket_count);
|
||||
|
||||
BOOST_CHECK_EQUAL(policy.bucket_for_hash(0), 0);
|
||||
BOOST_CHECK_EQUAL(bucket_count, 0);
|
||||
|
||||
#ifndef TSL_RH_NO_EXCEPTIONS
|
||||
bool exception_thrown = false;
|
||||
try {
|
||||
while(true) {
|
||||
const std::size_t previous_bucket_count = bucket_count;
|
||||
|
||||
bucket_count = policy.next_bucket_count();
|
||||
policy = Policy(bucket_count);
|
||||
|
||||
BOOST_CHECK_EQUAL(policy.bucket_for_hash(0), 0);
|
||||
BOOST_CHECK(bucket_count > previous_bucket_count);
|
||||
}
|
||||
}
|
||||
catch(const std::length_error& ) {
|
||||
exception_thrown = true;
|
||||
}
|
||||
|
||||
BOOST_CHECK(exception_thrown);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test_policy_min_bucket_count, Policy, test_types) {
|
||||
// Check policy when a bucket_count of 0 is asked.
|
||||
std::size_t bucket_count = 0;
|
||||
Policy policy(bucket_count);
|
||||
|
||||
BOOST_CHECK_EQUAL(policy.bucket_for_hash(0), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test_policy_max_bucket_count, Policy, test_types) {
|
||||
// Test a bucket_count equals to the max_bucket_count limit and above
|
||||
std::size_t bucket_count = 0;
|
||||
Policy policy(bucket_count);
|
||||
|
||||
|
||||
bucket_count = policy.max_bucket_count();
|
||||
Policy policy2(bucket_count);
|
||||
|
||||
|
||||
bucket_count = std::numeric_limits<std::size_t>::max();
|
||||
TSL_RH_CHECK_THROW((Policy(bucket_count)), std::length_error);
|
||||
|
||||
|
||||
bucket_count = policy.max_bucket_count() + 1;
|
||||
TSL_RH_CHECK_THROW((Policy(bucket_count)), std::length_error);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
1307
externals/robin-map/tests/robin_map_tests.cpp
vendored
Normal file
1307
externals/robin-map/tests/robin_map_tests.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
144
externals/robin-map/tests/robin_set_tests.cpp
vendored
Normal file
144
externals/robin-map/tests/robin_set_tests.cpp
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#define BOOST_TEST_DYN_LINK
|
||||
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include <tsl/robin_set.h>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(test_robin_set)
|
||||
|
||||
using test_types = boost::mpl::list<tsl::robin_set<std::int64_t>,
|
||||
tsl::robin_set<std::string>,
|
||||
tsl::robin_set<self_reference_member_test>,
|
||||
tsl::robin_set<move_only_test>,
|
||||
tsl::robin_pg_set<self_reference_member_test>,
|
||||
tsl::robin_set<move_only_test,
|
||||
std::hash<move_only_test>,
|
||||
std::equal_to<move_only_test>,
|
||||
std::allocator<move_only_test>,
|
||||
true,
|
||||
tsl::rh::prime_growth_policy>,
|
||||
tsl::robin_set<self_reference_member_test,
|
||||
std::hash<self_reference_member_test>,
|
||||
std::equal_to<self_reference_member_test>,
|
||||
std::allocator<self_reference_member_test>,
|
||||
true,
|
||||
tsl::rh::mod_growth_policy<>>,
|
||||
tsl::robin_set<move_only_test,
|
||||
std::hash<move_only_test>,
|
||||
std::equal_to<move_only_test>,
|
||||
std::allocator<move_only_test>,
|
||||
false,
|
||||
tsl::rh::mod_growth_policy<>>
|
||||
>;
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(test_insert, HSet, test_types) {
|
||||
// insert x values, insert them again, check values
|
||||
using key_t = typename HSet::key_type;
|
||||
|
||||
const std::size_t nb_values = 1000;
|
||||
HSet set;
|
||||
typename HSet::iterator it;
|
||||
bool inserted;
|
||||
|
||||
for(std::size_t i = 0; i < nb_values; i++) {
|
||||
std::tie(it, inserted) = set.insert(utils::get_key<key_t>(i));
|
||||
|
||||
BOOST_CHECK_EQUAL(*it, utils::get_key<key_t>(i));
|
||||
BOOST_CHECK(inserted);
|
||||
}
|
||||
BOOST_CHECK_EQUAL(set.size(), nb_values);
|
||||
|
||||
for(std::size_t i = 0; i < nb_values; i++) {
|
||||
std::tie(it, inserted) = set.insert(utils::get_key<key_t>(i));
|
||||
|
||||
BOOST_CHECK_EQUAL(*it, utils::get_key<key_t>(i));
|
||||
BOOST_CHECK(!inserted);
|
||||
}
|
||||
|
||||
for(std::size_t i = 0; i < nb_values; i++) {
|
||||
it = set.find(utils::get_key<key_t>(i));
|
||||
|
||||
BOOST_CHECK_EQUAL(*it, utils::get_key<key_t>(i));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_compare) {
|
||||
const tsl::robin_set<std::string> set1 = {"a", "e", "d", "c", "b"};
|
||||
const tsl::robin_set<std::string> set1_copy = {"e", "c", "b", "a", "d"};
|
||||
const tsl::robin_set<std::string> set2 = {"e", "c", "b", "a", "d", "f"};
|
||||
const tsl::robin_set<std::string> set3 = {"e", "c", "b", "a"};
|
||||
const tsl::robin_set<std::string> set4 = {"a", "e", "d", "c", "z"};
|
||||
|
||||
BOOST_CHECK(set1 == set1_copy);
|
||||
BOOST_CHECK(set1_copy == set1);
|
||||
|
||||
BOOST_CHECK(set1 != set2);
|
||||
BOOST_CHECK(set2 != set1);
|
||||
|
||||
BOOST_CHECK(set1 != set3);
|
||||
BOOST_CHECK(set3 != set1);
|
||||
|
||||
BOOST_CHECK(set1 != set4);
|
||||
BOOST_CHECK(set4 != set1);
|
||||
|
||||
BOOST_CHECK(set2 != set3);
|
||||
BOOST_CHECK(set3 != set2);
|
||||
|
||||
BOOST_CHECK(set2 != set4);
|
||||
BOOST_CHECK(set4 != set2);
|
||||
|
||||
BOOST_CHECK(set3 != set4);
|
||||
BOOST_CHECK(set4 != set3);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_insert_pointer) {
|
||||
// Test added mainly to be sure that the code compiles with MSVC due to a bug in the compiler.
|
||||
// See robin_hash::insert_value_impl for details.
|
||||
std::string value;
|
||||
std::string* value_ptr = &value;
|
||||
|
||||
tsl::robin_set<std::string*> set;
|
||||
set.insert(value_ptr);
|
||||
set.emplace(value_ptr);
|
||||
|
||||
BOOST_CHECK_EQUAL(set.size(), 1);
|
||||
BOOST_CHECK_EQUAL(**set.begin(), value);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
327
externals/robin-map/tests/utils.h
vendored
Normal file
327
externals/robin-map/tests/utils.h
vendored
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef TSL_UTILS_H
|
||||
#define TSL_UTILS_H
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <tsl/robin_hash.h>
|
||||
|
||||
#ifdef TSL_RH_NO_EXCEPTIONS
|
||||
#define TSL_RH_CHECK_THROW(S, E)
|
||||
#else
|
||||
#define TSL_RH_CHECK_THROW(S, E) BOOST_CHECK_THROW(S, E)
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
class identity_hash {
|
||||
public:
|
||||
std::size_t operator()(const T& value) const {
|
||||
return static_cast<std::size_t>(value);
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int MOD>
|
||||
class mod_hash {
|
||||
public:
|
||||
template<typename T>
|
||||
std::size_t operator()(const T& value) const {
|
||||
return std::hash<T>()(value) % MOD;
|
||||
}
|
||||
};
|
||||
|
||||
class self_reference_member_test {
|
||||
public:
|
||||
self_reference_member_test() : m_value(std::to_string(-1)), m_value_ptr(&m_value) {
|
||||
}
|
||||
|
||||
explicit self_reference_member_test(std::int64_t value) : m_value(std::to_string(value)), m_value_ptr(&m_value) {
|
||||
}
|
||||
|
||||
self_reference_member_test(const self_reference_member_test& other) : m_value(*other.m_value_ptr), m_value_ptr(&m_value) {
|
||||
}
|
||||
|
||||
self_reference_member_test(self_reference_member_test&& other) : m_value(*other.m_value_ptr), m_value_ptr(&m_value) {
|
||||
}
|
||||
|
||||
self_reference_member_test& operator=(const self_reference_member_test& other) {
|
||||
m_value = *other.m_value_ptr;
|
||||
m_value_ptr = &m_value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
self_reference_member_test& operator=(self_reference_member_test&& other) {
|
||||
m_value = *other.m_value_ptr;
|
||||
m_value_ptr = &m_value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string value() const {
|
||||
return *m_value_ptr;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const self_reference_member_test& value) {
|
||||
stream << *value.m_value_ptr;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
friend bool operator==(const self_reference_member_test& lhs, const self_reference_member_test& rhs) {
|
||||
return *lhs.m_value_ptr == *rhs.m_value_ptr;
|
||||
}
|
||||
|
||||
friend bool operator!=(const self_reference_member_test& lhs, const self_reference_member_test& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend bool operator<(const self_reference_member_test& lhs, const self_reference_member_test& rhs) {
|
||||
return *lhs.m_value_ptr < *rhs.m_value_ptr;
|
||||
}
|
||||
private:
|
||||
std::string m_value;
|
||||
std::string* m_value_ptr;
|
||||
};
|
||||
|
||||
|
||||
class move_only_test {
|
||||
public:
|
||||
explicit move_only_test(std::int64_t value) : m_value(new std::string(std::to_string(value))) {
|
||||
}
|
||||
|
||||
move_only_test(const move_only_test&) = delete;
|
||||
move_only_test(move_only_test&&) = default;
|
||||
move_only_test& operator=(const move_only_test&) = delete;
|
||||
move_only_test& operator=(move_only_test&&) = default;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const move_only_test& value) {
|
||||
if(value.m_value == nullptr) {
|
||||
stream << "null";
|
||||
}
|
||||
else {
|
||||
stream << *value.m_value;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
friend bool operator==(const move_only_test& lhs, const move_only_test& rhs) {
|
||||
if(lhs.m_value == nullptr || rhs.m_value == nullptr) {
|
||||
return lhs.m_value == nullptr && rhs.m_value == nullptr;
|
||||
}
|
||||
else {
|
||||
return *lhs.m_value == *rhs.m_value;
|
||||
}
|
||||
}
|
||||
|
||||
friend bool operator!=(const move_only_test& lhs, const move_only_test& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend bool operator<(const move_only_test& lhs, const move_only_test& rhs) {
|
||||
if(lhs.m_value == nullptr && rhs.m_value == nullptr) {
|
||||
return false;
|
||||
}
|
||||
else if(lhs.m_value == nullptr) {
|
||||
return true;
|
||||
}
|
||||
else if(rhs.m_value == nullptr) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return *lhs.m_value < *rhs.m_value;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& value() const {
|
||||
return *m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<std::string> m_value;
|
||||
};
|
||||
|
||||
|
||||
class copy_only_test {
|
||||
public:
|
||||
explicit copy_only_test(std::int64_t value): m_value(std::to_string(value)) {
|
||||
}
|
||||
|
||||
copy_only_test(const copy_only_test& other): m_value(other.m_value) {
|
||||
}
|
||||
|
||||
copy_only_test& operator=(const copy_only_test& other) {
|
||||
m_value = other.m_value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~copy_only_test() {
|
||||
}
|
||||
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, const copy_only_test& value) {
|
||||
stream << value.m_value;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
friend bool operator==(const copy_only_test& lhs, const copy_only_test& rhs) {
|
||||
return lhs.m_value == rhs.m_value;
|
||||
}
|
||||
|
||||
friend bool operator!=(const copy_only_test& lhs, const copy_only_test& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
friend bool operator<(const copy_only_test& lhs, const copy_only_test& rhs) {
|
||||
return lhs.m_value < rhs.m_value;
|
||||
}
|
||||
|
||||
std::string value() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
struct hash<self_reference_member_test> {
|
||||
std::size_t operator()(const self_reference_member_test& val) const {
|
||||
return std::hash<std::string>()(val.value());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<move_only_test> {
|
||||
std::size_t operator()(const move_only_test& val) const {
|
||||
return std::hash<std::string>()(val.value());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<copy_only_test> {
|
||||
std::size_t operator()(const copy_only_test& val) const {
|
||||
return std::hash<std::string>()(val.value());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class utils {
|
||||
public:
|
||||
template<typename T>
|
||||
static T get_key(std::size_t counter);
|
||||
|
||||
template<typename T>
|
||||
static T get_value(std::size_t counter);
|
||||
|
||||
template<typename HMap>
|
||||
static HMap get_filled_hash_map(std::size_t nb_elements);
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
inline std::int64_t utils::get_key<std::int64_t>(std::size_t counter) {
|
||||
return tsl::detail_robin_hash::numeric_cast<std::int64_t>(counter);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline self_reference_member_test utils::get_key<self_reference_member_test>(std::size_t counter) {
|
||||
return self_reference_member_test(tsl::detail_robin_hash::numeric_cast<std::int64_t>(counter));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string utils::get_key<std::string>(std::size_t counter) {
|
||||
return "Key " + std::to_string(counter);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline move_only_test utils::get_key<move_only_test>(std::size_t counter) {
|
||||
return move_only_test(tsl::detail_robin_hash::numeric_cast<std::int64_t>(counter));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline copy_only_test utils::get_key<copy_only_test>(std::size_t counter) {
|
||||
return copy_only_test(tsl::detail_robin_hash::numeric_cast<std::int64_t>(counter));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
inline std::int64_t utils::get_value<std::int64_t>(std::size_t counter) {
|
||||
return tsl::detail_robin_hash::numeric_cast<std::int64_t>(counter*2);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline self_reference_member_test utils::get_value<self_reference_member_test>(std::size_t counter) {
|
||||
return self_reference_member_test(tsl::detail_robin_hash::numeric_cast<std::int64_t>(counter*2));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string utils::get_value<std::string>(std::size_t counter) {
|
||||
return "Value " + std::to_string(counter);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline move_only_test utils::get_value<move_only_test>(std::size_t counter) {
|
||||
return move_only_test(tsl::detail_robin_hash::numeric_cast<std::int64_t>(counter*2));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline copy_only_test utils::get_value<copy_only_test>(std::size_t counter) {
|
||||
return copy_only_test(tsl::detail_robin_hash::numeric_cast<std::int64_t>(counter*2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename HMap>
|
||||
inline HMap utils::get_filled_hash_map(std::size_t nb_elements) {
|
||||
using key_t = typename HMap::key_type; using value_t = typename HMap:: mapped_type;
|
||||
|
||||
HMap map;
|
||||
map.reserve(nb_elements);
|
||||
|
||||
for(std::size_t i = 0; i < nb_elements; i++) {
|
||||
map.insert({utils::get_key<key_t>(i), utils::get_value<value_t>(i)});
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue