diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d3d5886 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.15) +project(mypkg CXX) + + + + +add_library(mypkg src/mypkg.cpp) +target_include_directories(mypkg PUBLIC include) + + + +set_target_properties(mypkg PROPERTIES PUBLIC_HEADER "include/mypkg.h") +install(TARGETS mypkg) diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 0000000..7b5f703 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,51 @@ +from conan import ConanFile +from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps + + +class pkgRecipe(ConanFile): + name = "HQueue" + version = "0.0" + package_type = "library" + + # Optional metadata + license = "GPLv3" + author = "HyperWinX" + description = "Multithreaded and customizable queue implementation" + + # Binary configuration + settings = "os", "compiler", "build_type", "arch" + options = {"shared": [True, False], "fPIC": [True, False]} + default_options = {"shared": False, "fPIC": True} + + # Sources are located in the same place as this recipe, copy them to the recipe + exports_sources = "CMakeLists.txt", "src/*", "include/*" + + def config_options(self): + if self.settings.os == "Windows": + self.options.rm_safe("fPIC") + + def configure(self): + if self.options.shared: + self.options.rm_safe("fPIC") + + def layout(self): + cmake_layout(self) + + def generate(self): + deps = CMakeDeps(self) + deps.generate() + tc = CMakeToolchain(self) + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + cmake = CMake(self) + cmake.install() + + def package_info(self): + self.cpp_info.libs = ["HQueue"] + diff --git a/include/hqueue.hpp b/include/hqueue.hpp new file mode 100644 index 0000000..a34789a --- /dev/null +++ b/include/hqueue.hpp @@ -0,0 +1,47 @@ +#include +#include +#include "internal/lambds_traits.hpp" +#include +#include +#include +#include +#include > + +namespace hqueue { + template + concept executor_t = requires(T a) { + std::is_invocable_v; + }; + + template + class queue { + public: + using return_type = typename function_traits::return_type; + using arguments = typename function_traits::argument_types; + + template + struct Task { + Args args; + //use std expected + } + + queue(std::uint16_t max_threads, executor_t executor) + : max_threads(max_threads) { + for (int i = 0; i < max_threads; ++i) { + m_threads.push_back([this](){ + { + std::unique_lock lck(m_mtx); + m_cv.wait(lck, [](){ return true; }); + } + + }); + } + } + private: + std::uint16_t max_threads; + std::vector m_threads; + std::mutex m_mtx; + std::condition_variable m_cv; + + } +} diff --git a/internal/lambda_traits.hpp b/internal/lambda_traits.hpp new file mode 100644 index 0000000..fb49010 --- /dev/null +++ b/internal/lambda_traits.hpp @@ -0,0 +1,34 @@ +// Credits to DeepSeek - I'm NOT writing all thatt +#pragma once + +#include +#include + +// Primary template – will use the operator() of the callable +template +struct function_traits : function_traits {}; + +// Specialization for function pointers +template +struct function_traits { + using return_type = R; + using argument_types = std::tuple; + static constexpr std::size_t arity = sizeof...(Args); +}; + +// Specialization for const member function pointers (lambdas & functors) +template +struct function_traits { + using return_type = R; + using argument_types = std::tuple; + static constexpr std::size_t arity = sizeof...(Args); +}; + +// Specialization for non‑const member function pointers (rare for lambdas) +template +struct function_traits { + using return_type = R; + using argument_types = std::tuple; + static constexpr std::size_t arity = sizeof...(Args); +}; + diff --git a/src/mypkg.cpp b/src/mypkg.cpp new file mode 100644 index 0000000..55fe1e5 --- /dev/null +++ b/src/mypkg.cpp @@ -0,0 +1,120 @@ +#include +#include "mypkg.h" + + + +void pkg(){ + + + #ifdef NDEBUG + std::cout << "mypkg/0.1: Hello World Release!\n"; + #else + std::cout << "mypkg/0.1: Hello World Debug!\n"; + #endif + + // ARCHITECTURES + #ifdef _M_X64 + std::cout << " mypkg/0.1: _M_X64 defined\n"; + #endif + + #ifdef _M_IX86 + std::cout << " mypkg/0.1: _M_IX86 defined\n"; + #endif + + #ifdef _M_ARM64 + std::cout << " mypkg/0.1: _M_ARM64 defined\n"; + #endif + + #if __i386__ + std::cout << " mypkg/0.1: __i386__ defined\n"; + #endif + + #if __x86_64__ + std::cout << " mypkg/0.1: __x86_64__ defined\n"; + #endif + + #if __aarch64__ + std::cout << " mypkg/0.1: __aarch64__ defined\n"; + #endif + + // Libstdc++ + #if defined _GLIBCXX_USE_CXX11_ABI + std::cout << " mypkg/0.1: _GLIBCXX_USE_CXX11_ABI "<< _GLIBCXX_USE_CXX11_ABI << "\n"; + #endif + + // MSVC runtime + #if defined(_DEBUG) + #if defined(_MT) && defined(_DLL) + std::cout << " mypkg/0.1: MSVC runtime: MultiThreadedDebugDLL\n"; + #elif defined(_MT) + std::cout << " mypkg/0.1: MSVC runtime: MultiThreadedDebug\n"; + #endif + #else + #if defined(_MT) && defined(_DLL) + std::cout << " mypkg/0.1: MSVC runtime: MultiThreadedDLL\n"; + #elif defined(_MT) + std::cout << " mypkg/0.1: MSVC runtime: MultiThreaded\n"; + #endif + #endif + + // COMPILER VERSIONS + #if _MSC_VER + std::cout << " mypkg/0.1: _MSC_VER" << _MSC_VER<< "\n"; + #endif + + #if _MSVC_LANG + std::cout << " mypkg/0.1: _MSVC_LANG" << _MSVC_LANG<< "\n"; + #endif + + #if __cplusplus + std::cout << " mypkg/0.1: __cplusplus" << __cplusplus<< "\n"; + #endif + + #if __INTEL_COMPILER + std::cout << " mypkg/0.1: __INTEL_COMPILER" << __INTEL_COMPILER<< "\n"; + #endif + + #if __GNUC__ + std::cout << " mypkg/0.1: __GNUC__" << __GNUC__<< "\n"; + #endif + + #if __GNUC_MINOR__ + std::cout << " mypkg/0.1: __GNUC_MINOR__" << __GNUC_MINOR__<< "\n"; + #endif + + #if __clang_major__ + std::cout << " mypkg/0.1: __clang_major__" << __clang_major__<< "\n"; + #endif + + #if __clang_minor__ + std::cout << " mypkg/0.1: __clang_minor__" << __clang_minor__<< "\n"; + #endif + + #if __apple_build_version__ + std::cout << " mypkg/0.1: __apple_build_version__" << __apple_build_version__<< "\n"; + #endif + + // SUBSYSTEMS + + #if __MSYS__ + std::cout << " mypkg/0.1: __MSYS__" << __MSYS__<< "\n"; + #endif + + #if __MINGW32__ + std::cout << " mypkg/0.1: __MINGW32__" << __MINGW32__<< "\n"; + #endif + + #if __MINGW64__ + std::cout << " mypkg/0.1: __MINGW64__" << __MINGW64__<< "\n"; + #endif + + #if __CYGWIN__ + std::cout << " mypkg/0.1: __CYGWIN__" << __CYGWIN__<< "\n"; + #endif +} + +void pkg_print_vector(const std::vector &strings) { + for(std::vector::const_iterator it = strings.begin(); it != strings.end(); ++it) { + std::cout << "pkg/0.1 " << *it << std::endl; + } +} diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt new file mode 100644 index 0000000..157693a --- /dev/null +++ b/test_package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.15) +project(PackageTest CXX) + +find_package(mypkg CONFIG REQUIRED) + +add_executable(example src/example.cpp) +target_link_libraries(example mypkg::mypkg) diff --git a/test_package/conanfile.py b/test_package/conanfile.py new file mode 100644 index 0000000..b515de0 --- /dev/null +++ b/test_package/conanfile.py @@ -0,0 +1,26 @@ +import os + +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout +from conan.tools.build import can_run + + +class pkgTestConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps", "CMakeToolchain" + + def requirements(self): + self.requires(self.tested_reference_str) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def layout(self): + cmake_layout(self) + + def test(self): + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "example") + self.run(cmd, env="conanrun") diff --git a/test_package/src/example.cpp b/test_package/src/example.cpp new file mode 100644 index 0000000..8ab1111 --- /dev/null +++ b/test_package/src/example.cpp @@ -0,0 +1,12 @@ +#include "mypkg.h" +#include +#include + +int main() { + pkg(); + + std::vector vec; + vec.push_back("test_package"); + + pkg_print_vector(vec); +}