diff --git a/.clangd b/.clangd new file mode 100644 index 00000000..527de5ae --- /dev/null +++ b/.clangd @@ -0,0 +1,3 @@ +CompileFlags: + Add: [ -Wall, -Wextra, -std=c++23 ] + Compiler: gcc \ No newline at end of file diff --git a/.envrc b/.envrc new file mode 100644 index 00000000..8392d159 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake \ No newline at end of file diff --git a/.gitignore b/.gitignore index 81e5c73d..b6f97437 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ result result-man outputs +.direnv diff --git a/flake.lock b/flake.lock index 62273058..c7d3a04f 100644 --- a/flake.lock +++ b/flake.lock @@ -54,22 +54,6 @@ "url": "https://flakehub.com/f/zhaofengli/attic/0.1.%2A.tar.gz" } }, - "biu": { - "flake": false, - "locked": { - "lastModified": 1711969538, - "narHash": "sha256-wGw+f7okXUDueWrUjRVqPb3Kx/OwIP8xrfvYRXbrAww=", - "owner": "CHN-beta", - "repo": "biu", - "rev": "dbdc36394271f859f25cabaceed971898741a1c6", - "type": "github" - }, - "original": { - "owner": "CHN-beta", - "repo": "biu", - "type": "github" - } - }, "blurred-wallpaper": { "flake": false, "locked": { @@ -1953,7 +1937,6 @@ "root": { "inputs": { "aagl": "aagl", - "biu": "biu", "blurred-wallpaper": "blurred-wallpaper", "chaotic": "chaotic", "citation-style-language": "citation-style-language", diff --git a/flake.nix b/flake.nix index fa11c1ed..27a4bb32 100644 --- a/flake.nix +++ b/flake.nix @@ -68,7 +68,6 @@ lmod = { url = "github:TACC/Lmod"; flake = false; }; mumax = { url = "github:CHN-beta/mumax"; flake = false; }; kylin-virtual-keyboard = { url = "git+https://gitee.com/openkylin/kylin-virtual-keyboard.git"; flake = false; }; - biu = { url = "github:CHN-beta/biu"; flake = false; }; }; outputs = inputs: @@ -175,5 +174,14 @@ overlays.default = final: prev: { localPackages = (import ./local/pkgs { inherit (inputs) lib; pkgs = final; topInputs = inputs; }); }; config.archive = false; + devShell.x86_64-linux = let inherit (inputs.self.nixosConfigurations.pc) pkgs; in pkgs.mkShell + { + packages = with pkgs; [ pkg-config cmake ninja clang-tools_17 ]; + buildInputs = + (with pkgs; [ fmt boost magic-enum libbacktrace eigen range-v3 ]) + ++ (with pkgs.localPackages; [ concurrencpp tgbot-cpp nameof ]); + # hardeningDisable = [ "all" ]; + # NIX_DEBUG = "1"; + }; }; } diff --git a/local/pkgs/biu/CMakeLists.txt b/local/pkgs/biu/CMakeLists.txt new file mode 100644 index 00000000..fa6e1163 --- /dev/null +++ b/local/pkgs/biu/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.14) +project(biu LANGUAGES CXX) +enable_testing() +include(GNUInstallDirs) + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message("Setting build type to 'Release' as none was specified.") + set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +endif() + +find_package(magic_enum REQUIRED) +find_package(fmt REQUIRED) +find_package(Boost REQUIRED COMPONENTS headers iostreams) +# find_package(concurrencpp REQUIRED) +find_package(Eigen3 REQUIRED) +find_package(range-v3 REQUIRED) +find_path(NAMEOF_INCLUDE_DIR nameof.hpp REQUIRED) +# find_path(TGBOTCPP_INCLUDE_DIR tgbot/tgbot.h REQUIRED) +# find_library(TGBOTCPP_LIB libTgBot.a REQUIRED) +# find_path(BACKTRACE_INCLUDE_DIR backtrace.h REQUIRED) +# find_library(BACKTRACE_LIB backtrace REQUIRED) + +# add_library(biu SHARED src/common.cpp src/logger.cpp src/string.cpp) +add_library(biu SHARED src/common.cpp) +target_include_directories(biu PUBLIC + $ + $ + ${NAMEOF_INCLUDE_DIR} ${TGBOTCPP_INCLUDE_DIR}) +target_link_libraries(biu PUBLIC + magic_enum::magic_enum + fmt::fmt + Boost::headers Boost::iostreams +# concurrencpp::concurrencpp + Eigen3::Eigen + range-v3::range-v3) +# ${TGBOTCPP_LIB} ${BACKTRACE_LIB}) +set_property(TARGET biu PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF) +install(TARGETS biu EXPORT biuConfig) +install(EXPORT biuConfig NAMESPACE ${PROJECT_NAME}:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/biu) +install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +get_property(ImportedTargets DIRECTORY "${CMAKE_SOURCE_DIR}" PROPERTY IMPORTED_TARGETS) +message("Imported targets: ${ImportedTargets}") +message("List of compile features: ${CMAKE_CXX_COMPILE_FEATURES}") diff --git a/local/pkgs/biu/default.nix b/local/pkgs/biu/default.nix new file mode 100644 index 00000000..d78d346c --- /dev/null +++ b/local/pkgs/biu/default.nix @@ -0,0 +1,10 @@ +{ + stdenv, cmake, + magic-enum, fmt, boost, eigen, range-v3, nameof +}: stdenv.mkDerivation +{ + name = "biu"; + src = ./.; + buildInputs = [ magic-enum fmt boost eigen range-v3 nameof ]; + nativeBuildInputs = [ cmake ]; +} diff --git a/local/pkgs/biu/include/biu.hpp b/local/pkgs/biu/include/biu.hpp new file mode 100644 index 00000000..4a9b713e --- /dev/null +++ b/local/pkgs/biu/include/biu.hpp @@ -0,0 +1,10 @@ +# pragma once +// # include +// # include +# include +// # include +// # include +// # include +// # include +// # include +# include diff --git a/local/pkgs/biu/include/biu/atomic/atomic.hpp b/local/pkgs/biu/include/biu/atomic/atomic.hpp new file mode 100644 index 00000000..1f13ddd9 --- /dev/null +++ b/local/pkgs/biu/include/biu/atomic/atomic.hpp @@ -0,0 +1,41 @@ +# pragma once +# include + +namespace biu::detail_ +{ + template class AtomicBase + : public Logger::ObjectMonitor>, protected AtomicBase + { + using DeepBase_ = AtomicBase; + using DeepBase_::AtomicBase; + public: class TimeoutException : public Logger::Exception + { + using Logger::Exception::Exception; + }; + + protected: template + < + bool ReturnFunctionResult, + typename ConditionFunction = std::nullptr_t, typename Duration = std::nullptr_t, bool Nothrow = false + > static auto apply_ + ( + auto&& atomic, auto&& function, + ConditionFunction&& condition_function = nullptr, Duration timeout = nullptr + ) -> DeepBase_::template ApplyReturnType_ + + requires DeepBase_::template ApplyConstraint_ + ; + + protected: template static auto wait_ + (auto&& atomic, auto&& condition_function, Duration timeout = nullptr) + -> DeepBase_::template WaitReturnType_ + requires DeepBase_::template WaitConstraint_; + + protected: template + + static auto lock_ + (auto&& atomic, ConditionFunction&& condition_function = nullptr, Duration timeout = nullptr) + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_; + }; +} diff --git a/local/pkgs/biu/include/biu/atomic/atomic.tpp b/local/pkgs/biu/include/biu/atomic/atomic.tpp new file mode 100644 index 00000000..e69de29b diff --git a/local/pkgs/biu/include/biu/atomic/nolog.hpp b/local/pkgs/biu/include/biu/atomic/nolog.hpp new file mode 100644 index 00000000..fd933407 --- /dev/null +++ b/local/pkgs/biu/include/biu/atomic/nolog.hpp @@ -0,0 +1,267 @@ +# pragma once +# include +# include +# include +# include +# include +# include +# include +# include + +namespace biu +{ + template class Atomic; + namespace detail_ + { + template class AtomicBase; + template class AtomicBase + { + protected: mutable std::recursive_mutex Mutex_; + protected: mutable std::condition_variable_any ConditionVariable_; + protected: ValueType Value_; + + AtomicBase() = default; + AtomicBase(const ValueType& value); + AtomicBase(ValueType&& value); + + public: class TimeoutException : public std::exception + { + protected: std::string Message_; + public: explicit TimeoutException(std::string message); + public: const char* what() const noexcept override; + }; + + // Apply a function to stored value. + // Wait for some time (if provided) until condition funciton returns true (if provided) + // before applying the function. + protected: template + < + typename Function, typename Atomic, + typename ConditionFunction = std::nullptr_t, typename Duration = std::nullptr_t + > + constexpr static bool ApplyConstraint_ = + ( + (std::invocable> && std::is_null_pointer_v) + || ( + InvocableWithResult + && (std::is_null_pointer_v || SpecializationOf) + ) + ); + protected: template + < + typename Function, typename Atomic, bool ReturnFunctionResult, + typename ConditionFunction = std::nullptr_t, typename Duration = std::nullptr_t, + bool Nothrow = false + > using ApplyReturnType_ = std::conditional_t + < + Nothrow, + std::conditional_t + < + ReturnFunctionResult && !std::is_void_v>, + std::optional, int>>>>, + bool + >, + std::conditional_t + < + ReturnFunctionResult, + std::invoke_result_t>, + Atomic&& + > + >; + protected: template + < + bool ReturnFunctionResult, + typename ConditionFunction = std::nullptr_t, typename Duration = std::nullptr_t, + bool Nothrow = false + > static auto apply_ + ( + auto&& atomic, auto&& function, + ConditionFunction&& condition_function = nullptr, Duration timeout = nullptr + ) -> ApplyReturnType_ + + requires ApplyConstraint_; + + // Wait until condition funciton returns true, with an optional timeout + protected: template + constexpr static bool WaitConstraint_ + = (InvocableWithResult + && (std::is_null_pointer_v || SpecializationOf)); + protected: template + + using WaitReturnType_ + = std::conditional_t, bool, Atomic&&>; + protected: template static auto wait_ + (auto&& atomic, auto&& condition_function, Duration timeout = nullptr) + -> WaitReturnType_ + requires WaitConstraint_; + + protected: template + constexpr static bool LockConstraint_ + = std::is_null_pointer_v || + ( + InvocableWithResult + && (std::is_null_pointer_v || SpecializationOf) + ); + protected: template + using LockReturnType_ + = std::conditional_t + < + Nothrow && !std::is_null_pointer_v, + std::optional, + typename std::remove_reference_t::template Guard, + typename std::remove_reference_t::template Guard + >>, + std::conditional_t + < + std::is_const_v, + typename std::remove_reference_t::template Guard, + typename std::remove_reference_t::template Guard + > + >; + protected: template + + static auto lock_ + (auto&& atomic, ConditionFunction&& condition_function = nullptr, Duration timeout = nullptr) + -> LockReturnType_ + requires LockConstraint_; + }; + } + + // Thread safe wrapper of custom class + template class Atomic : public detail_::AtomicBase + { + public: Atomic() = default; + public: Atomic(const ValueType& value); + public: Atomic(ValueType&& value); + public: template Atomic(const Atomic& other); + public: template Atomic(Atomic&& other); + public: Atomic& operator=(const ValueType& value); + public: Atomic& operator=(ValueType&& value); + public: template + Atomic& operator=(const Atomic& other); + public: template + Atomic& operator=(Atomic&& other); + public: ValueType get() const&; + public: ValueType get() &&; + public: operator ValueType() const&; + public: operator ValueType() &&; + + protected: using DeepBase_ = detail_::AtomicBase; + + public: template auto apply(auto&& function) const& + -> DeepBase_::template ApplyReturnType_ + requires DeepBase_::template ApplyConstraint_; + public: template auto apply(auto&& function) & + -> DeepBase_::template ApplyReturnType_ + requires DeepBase_::template ApplyConstraint_; + public: template auto apply(auto&& function) && + -> DeepBase_::template ApplyReturnType_ + requires DeepBase_::template ApplyConstraint_; + public: template + auto apply(auto&& function, auto&& condition_function) const& + -> DeepBase_::template ApplyReturnType_ + + requires DeepBase_::template ApplyConstraint_ + ; + public: template auto apply(auto&& function, auto&& condition_function) & + -> DeepBase_::template ApplyReturnType_ + + requires DeepBase_::template ApplyConstraint_ + ; + public: template auto apply(auto&& function, auto&& condition_function) && + -> DeepBase_::template ApplyReturnType_ + + requires DeepBase_::template ApplyConstraint_ + ; + public: template + auto apply(auto&& function, auto&& condition_function, auto timeout) const& + -> DeepBase_::template ApplyReturnType_ + < + decltype(function), decltype(*this), ReturnFunctionResult, + decltype(condition_function), decltype(timeout), Nothrow + > requires DeepBase_::template ApplyConstraint_ + ; + public: template + auto apply(auto&& function, auto&& condition_function, auto timeout) & + -> DeepBase_::template ApplyReturnType_ + < + decltype(function), decltype(*this), ReturnFunctionResult, + decltype(condition_function), decltype(timeout), Nothrow + > requires DeepBase_::template ApplyConstraint_ + ; + public: template + auto apply(auto&& function, auto&& condition_function, auto timeout) && + -> DeepBase_::template ApplyReturnType_ + < + decltype(function), decltype(*this), ReturnFunctionResult, + decltype(condition_function), decltype(timeout), Nothrow + > requires DeepBase_::template ApplyConstraint_ + ; + + public: auto wait(auto&& condition_function) const& + -> DeepBase_::template WaitReturnType_ + requires DeepBase_::template WaitConstraint_; + public: auto wait(auto&& condition_function) & + -> DeepBase_::template WaitReturnType_ + requires DeepBase_::template WaitConstraint_; + public: auto wait(auto&& condition_function) && + -> DeepBase_::template WaitReturnType_ + requires DeepBase_::template WaitConstraint_; + public: template auto wait(auto&& condition_function, auto timeout) const& + -> DeepBase_::template WaitReturnType_ + + requires DeepBase_::template WaitConstraint_; + public: template auto wait(auto&& condition_function, auto timeout) & + -> DeepBase_::template WaitReturnType_ + + requires DeepBase_::template WaitConstraint_; + public: template auto wait(auto&& condition_function, auto timeout) && + -> DeepBase_::template WaitReturnType_ + + requires DeepBase_::template WaitConstraint_; + + // Attain lock from outside when constructing, and release when destructing. + // For non-const variant, When destructing, ConditionVariable_.notify_all() is called. + public: template class Guard + { + protected: std::unique_lock Lock_; + protected: std::experimental::observer_ptr + , Atomic>> Value_; + + public: template Guard(const Guard& other) requires (Const || !OtherConst); + public: Guard + (decltype(Lock_)&& lock, decltype(Value_) value, CalledBy>); + public: ~Guard(); + + public: std::conditional_t operator*() const&; + public: std::conditional_t operator->() const&; + public: std::conditional_t value() const&; + public: auto operator*() const&& = delete; + public: auto operator->() const&& = delete; + public: auto value() const&& = delete; + }; + + public: auto lock() const& -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_<>; + public: auto lock() & -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_<>; + public: auto lock() const&& = delete; + public: auto lock(auto&& condition_function) const& + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_; + public: auto lock(auto&& condition_function) & + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_; + public: auto lock(auto&& condition_function) const&& = delete; + public: template auto lock(auto&& condition_function, auto timeout) const& + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_; + public: template auto lock(auto&& condition_function, auto timeout) & + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_; + public: template auto lock(auto&& condition_function, auto timeout) const&& = delete; + }; +} diff --git a/local/pkgs/biu/include/biu/atomic/nolog.tpp b/local/pkgs/biu/include/biu/atomic/nolog.tpp new file mode 100644 index 00000000..b4f98d31 --- /dev/null +++ b/local/pkgs/biu/include/biu/atomic/nolog.tpp @@ -0,0 +1,366 @@ +# pragma once +# include + +namespace biu +{ + template detail_::AtomicBase::AtomicBase(const ValueType& value) + : Value_{value} {} + template detail_::AtomicBase::AtomicBase(ValueType&& value) + : Value_{std::move(value)} {} + + template + detail_::AtomicBase::TimeoutException::TimeoutException(std::string) + : Message_{"TimeoutException"} {} + template + const char* detail_::AtomicBase::TimeoutException::what() const noexcept + {return Message_.c_str();} + + template + template + auto detail_::AtomicBase::apply_ + (auto&& atomic, auto&& function, ConditionFunction&& condition_function, Duration timeout) + -> ApplyReturnType_ + + requires ApplyConstraint_ + { + std::unique_lock lock{atomic.Mutex_}; + + // try to meet the condition + if constexpr (!std::is_null_pointer_v) + { + if constexpr (std::is_null_pointer_v) + atomic.ConditionVariable_.wait(lock, [&] + {return std::forward(condition_function)(std::as_const(atomic.Value_));}); + else if (!atomic.ConditionVariable_.wait_for(lock, timeout, [&] + {return std::forward(condition_function)(std::as_const(atomic.Value_));})) + { + if constexpr (Nothrow) + { + if constexpr + (ReturnFunctionResult && !std::is_void_v>) + return std::nullopt; + else return false; + } + else throw TimeoutException{}; + } + } + + // apply the function and return + if constexpr (ReturnFunctionResult && !std::is_void_v>) + { + auto&& result = std::forward(function) + (static_cast&&>(atomic.Value_)); + if constexpr (!std::is_const_v) atomic.ConditionVariable_.notify_all(); + return std::forward(result); + } + else + { + std::forward(function) + (static_cast&&>(atomic.Value_)); + if constexpr (!std::is_const_v) atomic.ConditionVariable_.notify_all(); + if constexpr (ReturnFunctionResult && std::is_void_v>) + return; + else return std::forward(atomic); + } + } + + template template + auto detail_::AtomicBase::wait_(auto&& atomic, auto&& condition_function, Duration timeout) + -> WaitReturnType_ + requires WaitConstraint_ + { + std::unique_lock lock{atomic.Mutex_}; + + if constexpr (std::is_null_pointer_v) + { + atomic.ConditionVariable_.wait(lock, [&] + {return std::forward(condition_function)(std::as_const(atomic.Value_));}); + return std::forward(atomic); + } + else + { + if (!atomic.ConditionVariable_.wait_for(lock, timeout, [&] + {return std::forward(condition_function)(std::as_const(atomic.Value_));})) + { + if constexpr (Nothrow) return false; + else throw TimeoutException{}; + } + else + { + if constexpr (Nothrow) return true; + else return std::forward(atomic); + } + } + } + + template template + auto detail_::AtomicBase::lock_ + (auto&& atomic, ConditionFunction&& condition_function, Duration timeout) + -> LockReturnType_ requires LockConstraint_ + { + if constexpr (std::is_null_pointer_v) + return {std::unique_lock{atomic.Mutex_}, std::experimental::make_observer(&atomic), {}}; + else if constexpr (std::is_null_pointer_v) + { + std::unique_lock lock{atomic.Mutex_}; + atomic.ConditionVariable_.wait(lock, [&] + {return std::forward(condition_function)(std::as_const(atomic.Value_));}); + return {std::move(lock), std::experimental::make_observer(&atomic), {}}; + } + else + { + std::unique_lock lock{atomic.Mutex_}; + if (!atomic.ConditionVariable_.wait_for(lock, timeout, [&] + {return std::forward(condition_function)(std::as_const(atomic.Value_));})) + { + if constexpr (Nothrow) return std::nullopt; + else throw TimeoutException{}; + } + else + return {{std::move(lock), std::experimental::make_observer(&atomic), {}}}; + } + } + + template Atomic::Atomic(const ValueType& value) + : detail_::AtomicBase{value} {} + template Atomic::Atomic(ValueType&& value) + : detail_::AtomicBase{std::move(value)} {} + template template + Atomic::Atomic(const Atomic& other) + : detail_::AtomicBase{other} {} + template template + Atomic::Atomic(Atomic&& other) + : detail_::AtomicBase{std::move(other)} {} + template + Atomic& Atomic::operator=(const ValueType& value) + { + std::scoped_lock lock{DeepBase_::Mutex_}; + DeepBase_::Value_ = value; + DeepBase_::ConditionVariable_.notify_all(); + return *this; + } + template + Atomic& Atomic::operator=(ValueType&& value) + { + std::scoped_lock lock{DeepBase_::Mutex_}; + DeepBase_::Value_ = std::move(value); + DeepBase_::ConditionVariable_.notify_all(); + return *this; + } + template template + Atomic& operator=(const Atomic& other) + { + std::scoped_lock lock{DeepBase_::Mutex_}; + DeepBase_::Value_ = value; + DeepBase_::ConditionVariable_.notify_all(); + return *this; + } + template template + Atomic& operator=(Atomic&& other) + { + std::scoped_lock lock{DeepBase_::Mutex_}; + DeepBase_::Value_ = std::move(value); + DeepBase_::ConditionVariable_.notify_all(); + return *this; + } + template ValueType Atomic::get() const& + { + std::scoped_lock lock{DeepBase_::Mutex_}; + return DeepBase_::Value_; + } + template ValueType Atomic::get() && + { + std::scoped_lock lock{DeepBase_::Mutex_}; + return std::move(DeepBase_::Value_); + } + template Atomic::operator ValueType() const& + {return get();} + template Atomic::operator ValueType() && + {return std::move(*this).get();} + + template template + auto Atomic::apply(auto&& function) const& + -> DeepBase_::template ApplyReturnType_ + requires DeepBase_::template ApplyConstraint_ + {return apply_(*this, std::forward(function));} + template template + auto Atomic::apply(auto&& function) & + -> DeepBase_::template ApplyReturnType_ + requires DeepBase_::template ApplyConstraint_ + {return apply_(*this, std::forward(function));} + template template + auto Atomic::apply(auto&& function) && + -> DeepBase_::template ApplyReturnType_ + requires DeepBase_::template ApplyConstraint_ + {return apply_(std::move(*this), std::forward(function));} + template template + auto Atomic::apply(auto&& function, auto&& condition_function) const& + -> DeepBase_::template ApplyReturnType_ + + requires DeepBase_::template ApplyConstraint_ + { + return apply_ + ( + *this, std::forward(function), + std::forward(condition_function) + ); + } + template template + auto Atomic::apply(auto&& function, auto&& condition_function) & + -> DeepBase_::template ApplyReturnType_ + + requires DeepBase_::template ApplyConstraint_ + { + return apply_ + ( + *this, std::forward(function), + std::forward(condition_function) + ); + } + template template + auto Atomic::apply(auto&& function, auto&& condition_function) && + -> DeepBase_::template ApplyReturnType_ + + requires DeepBase_::template ApplyConstraint_ + { + return apply_ + ( + std::move(*this), std::forward(function), + std::forward(condition_function) + ); + } + template template + auto Atomic::apply(auto&& function, auto&& condition_function, auto timeout) const& + -> DeepBase_::template ApplyReturnType_ + < + decltype(function), decltype(*this), ReturnFunctionResult, + decltype(condition_function), decltype(timeout), Nothrow + > requires DeepBase_::template ApplyConstraint_ + + { + return apply_ + ( + *this, std::forward(function), + std::forward(condition_function), timeout + ); + } + template template + auto Atomic::apply(auto&& function, auto&& condition_function, auto timeout) & + -> DeepBase_::template ApplyReturnType_ + < + decltype(function), decltype(*this), ReturnFunctionResult, + decltype(condition_function), decltype(timeout), Nothrow + > requires DeepBase_::template ApplyConstraint_ + + { + return apply_ + ( + *this, std::forward(function), + std::forward(condition_function), timeout + ); + } + template template + auto Atomic::apply(auto&& function, auto&& condition_function, auto timeout) && + -> DeepBase_::template ApplyReturnType_ + < + decltype(function), decltype(*this), ReturnFunctionResult, + decltype(condition_function), decltype(timeout), Nothrow + > requires DeepBase_::template ApplyConstraint_ + + { + return apply_ + ( + std::move(*this), std::forward(function), + std::forward(condition_function), timeout + ); + } + + template + auto Atomic::wait(auto&& condition_function) const& + -> DeepBase_::template WaitReturnType_ + requires DeepBase_::template WaitConstraint_ + {return wait_(*this, std::forward(condition_function));} + template + auto Atomic::wait(auto&& condition_function) & + -> DeepBase_::template WaitReturnType_ + requires DeepBase_::template WaitConstraint_ + {return wait_(*this, std::forward(condition_function));} + template + auto Atomic::wait(auto&& condition_function) && + -> DeepBase_::template WaitReturnType_ + requires DeepBase_::template WaitConstraint_ + {return wait_(std::move(*this), std::forward(condition_function));} + template template + auto Atomic::wait(auto&& condition_function, auto timeout) const& + -> DeepBase_::template WaitReturnType_ + + requires DeepBase_::template WaitConstraint_ + {return wait_(*this, std::forward(condition_function), timeout);} + template template + auto Atomic::wait(auto&& condition_function, auto timeout) & + -> DeepBase_::template WaitReturnType_ + + requires DeepBase_::template WaitConstraint_ + {return wait_(*this, std::forward(condition_function), timeout);} + template template + auto Atomic::wait(auto&& condition_function, auto timeout) && + -> DeepBase_::template WaitReturnType_ + + requires DeepBase_::template WaitConstraint_ + { + return wait_ + (std::move(*this), std::forward(condition_function), timeout); + } + + template template template + Atomic::Guard::Guard(const Guard& other) + requires (Const || !OtherConst) + : Lock_{other.Lock_}, Value_{other.Value_} {} + template template + Atomic::Guard::Guard + (decltype(Lock_)&& lock, decltype(Value_) value, CalledBy>) + : Lock_{std::move(lock)}, Value_{value} {} + template template + Atomic::Guard::~Guard() + {Value_->ConditionVariable_.notify_all();} + + template template + std::conditional_t + Atomic::Guard::operator*() const& + {return Value_->Value_;} + template template + std::conditional_t + Atomic::Guard::operator->() const& + {return &Value_->Value_;} + template template + std::conditional_t + Atomic::Guard::value() const& + {return Value_->Value_;} + + template auto Atomic::lock() const& + -> DeepBase_::template LockReturnType_ requires DeepBase_::template LockConstraint_<> + {return lock_(*this);} + template auto Atomic::lock() & + -> DeepBase_::template LockReturnType_ requires DeepBase_::template LockConstraint_<> + {return lock_(*this);} + template + auto Atomic::lock(auto&& condition_function) const& + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_ + {return lock_(*this, condition_function);} + template + auto Atomic::lock(auto&& condition_function) & + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_ + {return lock_(*this, condition_function);} + template template + auto Atomic::lock(auto&& condition_function, auto timeout) const& + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_ + {return lock_(*this, condition_function, timeout);} + template template + auto Atomic::lock(auto&& condition_function, auto timeout) & + -> DeepBase_::template LockReturnType_ + requires DeepBase_::template LockConstraint_ + {return lock_(*this, condition_function, timeout);} +} diff --git a/local/pkgs/biu/include/biu/called_by.hpp b/local/pkgs/biu/include/biu/called_by.hpp new file mode 100644 index 00000000..ee4254a2 --- /dev/null +++ b/local/pkgs/biu/include/biu/called_by.hpp @@ -0,0 +1,10 @@ +# pragma once + +namespace biu +{ + template class CalledBy + { + protected: CalledBy() = default; + friend AllowedType; + }; +} diff --git a/local/pkgs/biu/include/biu/common.hpp b/local/pkgs/biu/include/biu/common.hpp new file mode 100644 index 00000000..f6e35a5e --- /dev/null +++ b/local/pkgs/biu/include/biu/common.hpp @@ -0,0 +1,66 @@ +# pragma once +# include +# include +# include + +namespace biu +{ + std::size_t hash(auto&&... objs); + [[gnu::always_inline]] void unused(auto&&...); + + using uint128_t = __uint128_t; + + inline namespace literals + { + using namespace std::literals; + using namespace fmt::literals; + std::regex operator""_re(const char* str, std::size_t len); + } + + inline namespace stream_operators { using namespace magic_enum::iostream_operators; } + + struct CaseInsensitiveStringLessComparator + { + template constexpr bool operator()(const String& s1, const String& s2) const; + }; + + namespace detail_ + { + template struct RemoveMemberPointerHelper { using Type = T; }; + template struct RemoveMemberPointerHelper + { using Type = Member; }; + } + template using RemoveMemberPointer + = typename detail_::RemoveMemberPointerHelper::Type; + + [[noreturn]] void block_forever(); + + namespace detail_ + { + template struct MoveQualifiersHelper + { + protected: static constexpr bool Const_ = std::is_const_v; + protected: static constexpr bool Volatile_ = std::is_volatile_v; + protected: static constexpr bool Reference_ = std::is_reference_v; + protected: static constexpr bool Lvalue_ = std::is_lvalue_reference_v; + protected: using NoCvrefType_ = std::remove_cvref_t; + protected: using NoCvType_ + = std::conditional_t, NoCvrefType_>; + protected: using NoConstType_ = std::conditional_t; + public: using Type = std::conditional_t; + }; + } + template using MoveQualifiers + = typename detail_::MoveQualifiersHelper::Type; + + namespace detail_ + { + template struct FallbackIfNoTypeDeclaredHelper { using Type = Fallback; }; + template requires requires { typename T::Type; } + struct FallbackIfNoTypeDeclaredHelper { using Type = typename T::Type; }; + template requires requires {typename T::type;} + struct FallbackIfNoTypeDeclaredHelper { using Type = typename T::type; }; + } + template using FallbackIfNoTypeDeclared + = typename detail_::FallbackIfNoTypeDeclaredHelper::Type; +} diff --git a/local/pkgs/biu/include/biu/common.tpp b/local/pkgs/biu/include/biu/common.tpp new file mode 100644 index 00000000..7cbf42ae --- /dev/null +++ b/local/pkgs/biu/include/biu/common.tpp @@ -0,0 +1,24 @@ +# pragma once +# include +# include + +namespace biu +{ + inline void unused(auto&&...) {} + inline std::size_t hash(auto&&... objs) + { + std::size_t result = 0; + (boost::hash_combine(result, objs), ...); + return result; + } + + template inline constexpr bool CaseInsensitiveStringLessComparator::operator() + (const String& s1, const String& s2) const + { + return std::lexicographical_compare + ( + s1.begin(), s1.end(), s2.begin(), s2.end(), + [](char c1, char c2){return std::tolower(c1) < std::tolower(c2);} + ); + } +} \ No newline at end of file diff --git a/local/pkgs/biu/include/biu/concepts.hpp b/local/pkgs/biu/include/biu/concepts.hpp new file mode 100644 index 00000000..42176990 --- /dev/null +++ b/local/pkgs/biu/include/biu/concepts.hpp @@ -0,0 +1,47 @@ +# pragma once +# include +# include +# include +# include + +namespace biu +{ + template concept DecayedType = std::same_as, T>; + + namespace detail_::specialization_of_detail_ + { + template struct DropFirstMemberOfTupleHelper; + template struct DropFirstMemberOfTupleHelper> + {using Type = std::tuple;}; + template consteval bool check_provided_args(); + template typename Template> struct SpecializationOfHelper + {template consteval static bool check_provided_args();}; + template