first commit

This commit is contained in:
Bob Polis 2020-03-16 15:11:40 +01:00
commit 2dc9475ef7
5 changed files with 251 additions and 0 deletions

6
Makefile Normal file
View File

@ -0,0 +1,6 @@
HDRS := $(wildcard *.hpp)
PREFIX ?= /usr/local/include
install: $(HDRS)
mkdir -p $(PREFIX)/sc
install -c -m 0666 $(HDRS) $(PREFIX)/sc

44
functools.hpp Normal file
View File

@ -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 <vector>
#include <functional>
#include <algorithm>
#include <iterator>
namespace sc {
template<class T, class M>
std::vector<M> map(const std::vector<T>& seq, std::function<M(T)> fun) {
std::vector<M> result;
std::transform(seq.begin(), seq.end(), back_inserter(result), fun);
return result;
}
template<class T>
std::vector<T> filter(const std::vector<T>& seq, std::function<bool(T)> fun) {
std::vector<T> result;
std::copy_if(seq.begin(), seq.end(), back_inserter(result), fun);
return result;
}
template<class T, class R>
R reduce(const std::vector<T>& seq, R seed, std::function<R(T, R)> fun) {
R result {seed};
for (const auto& elem : seq) {
result = fun(elem, result);
}
return result;
}
}
#endif // _functools_H_

29
integer_locale.hpp Normal file
View File

@ -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<char> {
public:
typedef char char_type;
typedef std::string string_type;
explicit integer_locale(size_t r = 0) : std::numpunct<char>(r) {}
protected:
char do_decimal_point() const { return ','; }
char do_thousands_sep() const { return '.'; }
std::string do_grouping() const { return "\003"; }
};
}
#endif

128
plugin.hpp Normal file
View File

@ -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 <memory>
#include <string>
#include <map>
#include <functional>
#include <iostream>
#include <dlfcn.h>
#include <dirent.h>
namespace sc {
template <typename T>
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<void(const plugin&)>;
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<std::string> names() {
std::vector<std::string> 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<factory>(::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<T> operator()() const {
std::unique_ptr<T> obj;
if (_factory) {
obj.reset(_factory());
}
return obj;
}
private:
static std::map<std::string, plugin<T>> plugins;
std::string _path;
void* _plugin {nullptr};
using factory = T*(*)();
factory _factory {nullptr};
};
template <typename T>
std::map<std::string, plugin<T>> plugin<T>::plugins;
}
#endif // _plugin_H_

44
sync_queue.hpp Normal file
View File

@ -0,0 +1,44 @@
//
// Sync_queue.h
// adapted from an example from Bjarne Stroustrup
//
#ifndef __Sync_queue__
#define __Sync_queue__
#include <mutex>
#include <condition_variable>
#include <list>
#include <future>
#include <thread>
namespace sc {
template<typename T>
class Sync_queue {
public:
void put(const T& val)
{
std::lock_guard<std::mutex> lck {mtx};
q.push_back(val);
cond.notify_one();
}
T get()
{
std::unique_lock<std::mutex> 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<T> q;
};
}
#endif /* defined(__Sync_queue__) */