commit 2dc9475ef7dcd2c472eb84655f85cd2921c6fe90 Author: Bob Polis Date: Mon Mar 16 15:11:40 2020 +0100 first commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..293c8ce --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +HDRS := $(wildcard *.hpp) +PREFIX ?= /usr/local/include + +install: $(HDRS) + mkdir -p $(PREFIX)/sc + install -c -m 0666 $(HDRS) $(PREFIX)/sc diff --git a/functools.hpp b/functools.hpp new file mode 100644 index 0000000..138abf1 --- /dev/null +++ b/functools.hpp @@ -0,0 +1,44 @@ +// +// functools.hpp +// libcommon +// +// Created by Bob Polis at 2019-10-19 +// Copyright (c) 2019 SwiftCoder. All rights reserved. +// + +#ifndef _functools_H_ +#define _functools_H_ + +#include +#include +#include +#include + +namespace sc { + + template + std::vector map(const std::vector& seq, std::function fun) { + std::vector result; + std::transform(seq.begin(), seq.end(), back_inserter(result), fun); + return result; + } + + template + std::vector filter(const std::vector& seq, std::function fun) { + std::vector result; + std::copy_if(seq.begin(), seq.end(), back_inserter(result), fun); + return result; + } + + template + R reduce(const std::vector& seq, R seed, std::function fun) { + R result {seed}; + for (const auto& elem : seq) { + result = fun(elem, result); + } + return result; + } + +} + +#endif // _functools_H_ diff --git a/integer_locale.hpp b/integer_locale.hpp new file mode 100644 index 0000000..d3ae27c --- /dev/null +++ b/integer_locale.hpp @@ -0,0 +1,29 @@ +// +// integer_locale.h +// locales +// +// Created by Thalictrum on 13-05-2012. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef locales_integer_locale_h +#define locales_integer_locale_h + +namespace sc { + + class integer_locale : public std::numpunct { + public: + typedef char char_type; + typedef std::string string_type; + + explicit integer_locale(size_t r = 0) : std::numpunct(r) {} + + protected: + char do_decimal_point() const { return ','; } + char do_thousands_sep() const { return '.'; } + std::string do_grouping() const { return "\003"; } + }; + +} + +#endif diff --git a/plugin.hpp b/plugin.hpp new file mode 100644 index 0000000..7fa6c58 --- /dev/null +++ b/plugin.hpp @@ -0,0 +1,128 @@ +// +// plugin.hpp +// plugins +// +// Created by Bob Polis at 2019-06-09 +// Copyright (c) 2019 SwiftCoder. All rights reserved. +// + +#ifndef _plugin_H_ +#define _plugin_H_ + +#include +#include +#include +#include +#include + +#include +#include + +namespace sc { + + template + class plugin { + public: + static void scan_plugins(const std::string& dir, const std::string& ext) { + DIR* plugins_dir = ::opendir(dir.c_str()); + throw_if_null_msg(plugins_dir, (dir + " could not be opened").c_str()); + struct dirent* info; + while ((info = ::readdir(plugins_dir)) != nullptr) { + if (info->d_name[0] != '.') { + std::string plugname {info->d_name}; + std::string::size_type lastdot = plugname.rfind("."); + if (plugname.substr(lastdot + 1) == ext) { + + } + plugin plugin {dir + '/' + plugname}; + plugins.emplace(plugname.substr(0, lastdot), std::move(plugin)); + } + } + throw_if_min1(::closedir(plugins_dir)); + } + + using processor = std::function; + static void foreach(processor proc) { + for (const auto& elem : plugins) { + proc(elem.second); + } + } + + static plugin& get(const std::string& name) { + return plugins.at(name); + } + + static std::vector names() { + std::vector result; + for (const auto& elem : plugins) { + result.emplace_back(elem.first); + } + return result; + } + + plugin(const std::string& path) : _path {path} { + _plugin = ::dlopen(path.c_str(), RTLD_LAZY); + std::cerr << path << (_plugin ? "" : " not") << " opened\n"; + const char* err {::dlerror()}; + if (err) std::cerr << err << '\n'; + if (_plugin) { + _factory = reinterpret_cast(::dlsym(_plugin, "create_instance")); + if (!_factory) { + std::cerr << "create_instance() function not found in " << path << '\n'; + } + } + } + + ~plugin() { + if (_plugin) { + ::dlclose(_plugin); + _plugin = nullptr; + std::cerr << _path << " closed\n"; + } + } + + plugin(const plugin&) = delete; + plugin& operator=(const plugin&) = delete; + + plugin(plugin&& other) { + _path = other._path; + _plugin = other._plugin; + _factory = other._factory; + other._plugin = nullptr; + } + + plugin& operator=(plugin&& other) { + if (this != &other) { + _path = other._path; + _plugin = other._plugin; + _factory = other._factory; + other._plugin = nullptr; + } + return *this; + } + + std::string path() const { return _path; } + + std::unique_ptr operator()() const { + std::unique_ptr obj; + if (_factory) { + obj.reset(_factory()); + } + return obj; + } + + private: + static std::map> plugins; + + std::string _path; + void* _plugin {nullptr}; + using factory = T*(*)(); + factory _factory {nullptr}; + }; + + template + std::map> plugin::plugins; + +} + +#endif // _plugin_H_ diff --git a/sync_queue.hpp b/sync_queue.hpp new file mode 100644 index 0000000..5be6b1b --- /dev/null +++ b/sync_queue.hpp @@ -0,0 +1,44 @@ +// +// Sync_queue.h +// adapted from an example from Bjarne Stroustrup +// + +#ifndef __Sync_queue__ +#define __Sync_queue__ + +#include +#include +#include +#include +#include + +namespace sc { + + template + class Sync_queue { + public: + void put(const T& val) + { + std::lock_guard lck {mtx}; + q.push_back(val); + cond.notify_one(); + } + + T get() + { + std::unique_lock lck {mtx}; + cond.wait(lck, [this]{ return !q.empty(); }); + T val {q.front()}; + q.pop_front(); + return val; + } + + private: + std::mutex mtx; + std::condition_variable cond; + std::list q; + }; + +} + +#endif /* defined(__Sync_queue__) */