first commit
This commit is contained in:
		
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										44
									
								
								functools.hpp
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										29
									
								
								integer_locale.hpp
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										128
									
								
								plugin.hpp
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										44
									
								
								sync_queue.hpp
									
									
									
									
									
										Normal 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__) */ | ||||||
		Reference in New Issue
	
	Block a user
	 Bob Polis
					Bob Polis