diff --git a/.gitignore b/.gitignore index 7fbfa51..11eb870 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /cmake-build-*/ -tests/cmake-build-*/ \ No newline at end of file +tests/cmake-build-*/ +.vs/ +out/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c862ed4..6532c31 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,8 +117,12 @@ if(${BUILD_TESTS}) target_link_libraries(BLT_TESTS BLT) - target_compile_options(BLT_TESTS PRIVATE -Wall -Werror -Wpedantic -Wno-comment) - target_link_options(BLT_TESTS PRIVATE -Wall -Werror -Wpedantic -Wno-comment) + if(MSVC) + + else() + target_compile_options(BLT_TESTS PRIVATE -Wall -Werror -Wpedantic -Wno-comment) + target_link_options(BLT_TESTS PRIVATE -Wall -Werror -Wpedantic -Wno-comment) + endif() if (${ENABLE_ADDRSAN} MATCHES ON) target_compile_options(BLT_TESTS PRIVATE -fsanitize=address) diff --git a/include/blt/compatibility.h b/include/blt/compatibility.h index 359cd6b..fe5a97b 100644 --- a/include/blt/compatibility.h +++ b/include/blt/compatibility.h @@ -30,6 +30,8 @@ #undef BLT_USE_CPP20 #endif +#define BLT_CONTAINS_IF(container, value) std::find_if(container.begin(), container.end(), value) != container.end() + #define INCLUDE_FS \ #if defined(CXX17_FILESYSTEM) || defined (CXX17_FILESYSTEM_LIBFS) \ #include \ diff --git a/include/blt/math/math.h b/include/blt/math/math.h index 7c2ff50..9e0b78d 100755 --- a/include/blt/math/math.h +++ b/include/blt/math/math.h @@ -10,22 +10,35 @@ #include #include -namespace blt { +namespace blt +{ + + static inline constexpr double PI = 3.141592653589793238462643383279502884197; + + template + static inline T toRadians(T deg) + { + constexpr double CONV = PI / 180.0; + return deg * CONV; + } /** * fast number integer */ - static inline unsigned int f_randi(unsigned int seed) { + static inline unsigned int f_randi(unsigned int seed) + { seed = (seed << 13) ^ seed; return ((seed * (seed * seed * 15731 + 789221) + 1376312589) & 0x7fffffff); } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-aliasing" + /** * fast inverse sqrt */ - static inline float fsqrt(float n){ + static inline float fsqrt(float n) + { int i; float x, y; x = n * 0.5f; @@ -41,7 +54,8 @@ namespace blt { #pragma GCC diagnostic pop - static inline constexpr double pow(int b, int p) { + static inline constexpr double pow(int b, int p) + { int collection = 1; for (int i = 0; i < p; i++) collection *= b; @@ -55,9 +69,10 @@ namespace blt { * @return */ template - static inline double round_up(double value) { + static inline double round_up(double value) + { constexpr double multiplier = pow(10, decimal_places); - return ((int)(value * multiplier) + 1) / multiplier; + return ((int) (value * multiplier) + 1) / multiplier; } /*inline std::ostream& operator<<(std::ostream& out, const mat4x4& v) { @@ -66,7 +81,7 @@ namespace blt { << " {" << v.m20() << ", " << v.m21() << ", " << v.m22() << ", " << v.m23() << "} \n"\ << " {" << v.m30() << ", " << v.m31() << ", " << v.m32() << ", " << v.m33() << "} \n"; }*/ - + } #endif //BLT_MATH_H diff --git a/include/blt/math/vectors.h b/include/blt/math/vectors.h index 9646086..15232f1 100755 --- a/include/blt/math/vectors.h +++ b/include/blt/math/vectors.h @@ -267,6 +267,11 @@ namespace blt { return true; } + template + inline constexpr bool operator!=(const vec& left, const vec& right) { + return !(left == right); + } + template inline constexpr bool operator&&(const vec& left, const vec& right) { for (uint32_t i = 0; i < size; i++) diff --git a/include/blt/std/memory_util.h b/include/blt/std/memory_util.h index b7e2e8b..7802e77 100644 --- a/include/blt/std/memory_util.h +++ b/include/blt/std/memory_util.h @@ -23,6 +23,7 @@ #include #include #include +#include #if defined(__clang__) || defined(__llvm__) || defined(__GNUC__) || defined(__GNUG__) @@ -32,9 +33,9 @@ #define SWAP32(val) bswap_32(val) #define SWAP64(val) bswap_64(val) #if __cplusplus >= 202002L - + #include - + #define ENDIAN_LOOKUP(little_endian) (std::endian::native == std::endian::little && !little_endian) || \ (std::endian::native == std::endian::big && little_endian) #else @@ -109,6 +110,15 @@ namespace blt::mem return prev_size * 2; return prev_size + default_allocation_block; } + + template + inline static R type_cast(T type) + { + static_assert(sizeof(T) == sizeof(R)); + R r; + std::memcpy(&r, &type, sizeof(type)); + return r; + } } #endif //BLT_MEMORY_UTIL_H diff --git a/include/blt/std/thread.h b/include/blt/std/thread.h new file mode 100644 index 0000000..73bd727 --- /dev/null +++ b/include/blt/std/thread.h @@ -0,0 +1,132 @@ +/* + * + * Copyright (C) 2023 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BLT_THREAD_H +#define BLT_THREAD_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace blt +{ + /** + * @tparam queue should we use a queue or execute the same function over and over? + */ + template + class thread_pool + { + private: + typedef std::function thread_function; + volatile std::atomic_bool should_stop = false; + volatile std::atomic_uint64_t stopped = 0; + std::uint64_t number_of_threads = 0; + std::vector threads; + std::variant, thread_function> func_queue; + std::mutex queue_mutex; + public: + explicit thread_pool(std::uint64_t number_of_threads = 8, std::optional default_function = {}) + { + if (default_function.has_value()) + func_queue = default_function.value(); + this->number_of_threads = number_of_threads; + for (std::uint64_t i = 0; i < number_of_threads; i++) + { + threads.push_back(new std::thread([this]() { + while (!should_stop) + { + if constexpr (queue) + { + // should be safe right? + std::unique_lock lock(queue_mutex); + lock.lock(); + auto& func_q = std::get>(func_queue); + if (func_q.empty()) + { + lock.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(16)); + continue; + } + auto func = func_q.front(); + func_q.pop(); + lock.unlock(); + func(); + } else + { + { + std::scoped_lock lock(queue_mutex); + if (std::holds_alternative>(func_queue)) + { + std::this_thread::sleep_for(std::chrono::milliseconds(16)); + BLT_WARN("Running non queue variant with a queue inside!"); + break; + } + } + auto& func = std::get(func_queue); + func(); + } + } + stopped++; + })); + } + } + + inline void execute(const thread_function& func) + { + std::scoped_lock lock(queue_mutex); + if constexpr (queue) + { + auto& v = std::get>(func_queue); + v.push(func); + } else + { + func_queue = func; + } + } + + [[nodiscard]] inline bool complete() const { + return stopped == number_of_threads; + } + + inline void stop() + { + should_stop = true; + } + + ~thread_pool() + { + should_stop = true; + for (auto* t : threads) + { + if (t->joinable()) + t->join(); + delete t; + } + } + }; +} + +#endif //BLT_THREAD_H diff --git a/include/blt/std/time.h b/include/blt/std/time.h index 8a43163..daec649 100755 --- a/include/blt/std/time.h +++ b/include/blt/std/time.h @@ -73,7 +73,7 @@ namespace blt::system clock_getres(CLOCK_PROCESS_CPUTIME_ID, &res); return res.tv_sec * static_cast(1e9) + res.tv_nsec; #else - return CLOCKS_PER_SECOND; + return 1; #endif } diff --git a/include/blt/std/utility.h b/include/blt/std/utility.h index bbf8679..b007bb0 100644 --- a/include/blt/std/utility.h +++ b/include/blt/std/utility.h @@ -20,11 +20,11 @@ #define BLT_UTILITY_H #include +#include #if defined(__GNUC__) #include - #include namespace blt { @@ -238,7 +238,7 @@ namespace blt #endif template - void BLT_ATTRIB_NO_INLINE black_box(const T& val) + BLT_ATTRIB_NO_INLINE void black_box(const T& val) { static volatile void* hell; hell = (void*) &val; @@ -246,7 +246,7 @@ namespace blt } template - const T& BLT_ATTRIB_NO_INLINE black_box_ret(const T& val) + BLT_ATTRIB_NO_INLINE const T& black_box_ret(const T& val) { static volatile void* hell; hell = (void*) &val; diff --git a/libraries/parallel-hashmap b/libraries/parallel-hashmap index 401552d..946ebad 160000 --- a/libraries/parallel-hashmap +++ b/libraries/parallel-hashmap @@ -1 +1 @@ -Subproject commit 401552da80b0971f818e648621260720ad40934e +Subproject commit 946ebad67a21212d11a0dd4deb7cdedc297d47bc