#pragma once #ifdef DEBUG #define BOOST_DI_CFG_DIAGNOSTICS_LEVEL 2 #endif #include <atomic> #include <boost/di.hpp> #include <boost/optional.hpp> #include <cassert> #include <cerrno> #include <chrono> #include <cstring> #include <functional> #include <map> #include <memory> #include <string> #include <thread> #include <vector> #include "config.hpp" #define LEMONBUDDY_NS \ namespace lemonbuddy { \ inline namespace v2_0_0 { #define LEMONBUDDY_NS_END \ } \ } #define LEMONBUDDY_NS_PATH "lemonbuddy::v2_0_0" #define PIPE_READ 0 #define PIPE_WRITE 1 #ifdef DEBUG #include "debug.hpp" #endif LEMONBUDDY_NS //================================================== // Include common types (i.e, unclutter editor!) //================================================== namespace di = boost::di; namespace chrono = std::chrono; namespace this_thread = std::this_thread; namespace placeholders = std::placeholders; using namespace std::chrono_literals; using std::string; using std::stringstream; using std::size_t; using std::move; using std::bind; using std::forward; using std::pair; using std::function; using std::shared_ptr; using std::unique_ptr; using std::make_unique; using std::make_shared; using std::make_pair; using std::array; using std::map; using std::vector; using std::to_string; using std::strerror; using std::getenv; using std::thread; using std::exception; using boost::optional; using stateflag = std::atomic<bool>; //================================================== // Instance factory //================================================== namespace factory { template <class InstanceType, class... Deps> unique_ptr<InstanceType> generic_instance(Deps... deps) { return make_unique<InstanceType>(deps...); } template <class InstanceType, class... Deps> shared_ptr<InstanceType> generic_singleton(Deps... deps) { static auto instance = make_shared<InstanceType>(deps...); return instance; } } struct null_deleter { template <typename T> void operator()(T*) const {} }; //================================================== // Errors and exceptions //================================================== class application_error : public std::runtime_error { public: int m_code; explicit application_error(string&& message, int code = 0) : std::runtime_error(forward<string>(message)), m_code(code) {} }; class system_error : public application_error { public: explicit system_error() : application_error(strerror(errno), errno) {} explicit system_error(string&& message) : application_error(forward<string>(message) + " (reason: " + strerror(errno) + ")", errno) {} }; #define DEFINE_CHILD_ERROR(error, parent) \ class error : public parent { \ using parent::parent; \ } #define DEFINE_ERROR(error) DEFINE_CHILD_ERROR(error, application_error) //================================================== // Various tools and helpers functions //================================================== auto has_env = [](const char* var) { return getenv(var) != nullptr; }; auto read_env = [](const char* var, string&& fallback = "") { const char* value{getenv(var)}; return value != nullptr ? value : fallback; }; template <class T> auto time_execution(const T& expr) noexcept { auto start = std::chrono::high_resolution_clock::now(); expr(); auto finish = std::chrono::high_resolution_clock::now(); return std::chrono::duration_cast<std::chrono::milliseconds>(finish - start).count(); } template <typename... Args> using callback = function<void(Args...)>; LEMONBUDDY_NS_END