#pragma once namespace Utils { std::string GetMimeType(std::string url); std::string ParseChallenge(std::string data); void OutputDebugLastError(); std::string GetLastWindowsError(); bool IsWineEnvironment(); unsigned long GetParentProcessId(); template inline void Merge(std::vector* target, T* source, size_t length) { if (source) { for (size_t i = 0; i < length; ++i) { target->push_back(source[i]); } } } template inline void Merge(std::vector* target, std::vector source) { for (auto &entry : source) { target->push_back(entry); } } template using Slot = std::function; template class Signal { public: Signal() { this->slots.clear(); } Signal(Signal& obj) : Signal() { Utils::Merge(&this->slots, obj.getSlots()); } void connect(Slot slot) { if (slot) { this->slots.push_back(slot); } } void clear() { this->slots.clear(); } std::vector>& getSlots() { return this->slots; } template void operator()(Args&&... args) const { std::vector> copiedSlots; Utils::Merge(&copiedSlots, this->slots); for (auto slot : copiedSlots) { if (slot) { slot(std::forward(args)...); } } } private: std::vector> slots; }; // TODO: Replace with std::optional, once C++17 is fully available! template class Value { public: Value() : hasValue(false) {} Value(T _value) { this->set(_value); } void set(T _value) { this->value = _value; this->hasValue = true; } bool isValid() { return this->hasValue; } T get() { return this->value; } private: bool hasValue; T value; }; }