Dispatch Tool for Modern C++
~$ cmake -Bbuild -H.
~$ cmake --build build --target install
#include <oyoung/any.hpp>
#include <iostream>
int main(int argc, char **argv)
{
oyoung::any any {1, 2, 3, 4, 5, 6, 7};
any.push_back(100);
for(auto n: any) {
std::cout << oyoung::any_cast<int>(n) << std::endl;
}
any = oyoung::any::object_t { {"name", "oyoung"}, {"age", 27} };
any.insert("gender", "Male");
for(auto it = any.begin(); it != any.end(); ++it) {
auto value = it.value();
std::cout << it.key() << ": ";
if(value.is_string()) {
std::cout << oyoung::any_cast<std::string>(value);
} else if(value.is_number_integer()) {
std::cout << oyoung::any_cast<int>(value);
}
std::cout << std::endl;
}
return 0;
}
#include <oyoung/dispatch.hpp>
#include <iostream>
int main(int argc, char **argv)
{
auto queue = oyoung::dispatch_queue_create("name");
oyoung::async(*queue, [=] {
std::cout << "dispatch async calling" << std::endl;
});
std::cout << "dispatch sync will call" << std::endl;
oyoung::sync(*queue, [=] {
std::cout << "dispatch sync calling" << std::endl;
});
std::cout << "dispatch sync called" << std::endl;
return 0;
}
#include <oyoung/dispatch.hpp>
#include <iostream>
int main(int argc, char **argv)
{
auto task = oyoung::promise<int>([] {
int result = 0;
// do something to update the result;
return result;
}).then<int>([](int n /*last return value*/) {
int another_result = 0;
// do other things
return another_result;
});
try {
std::cout << task.get() << std::endl;
} catch(const std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
example code:
#include <oyoung/event.hpp>
#include <ev++.h>
#include <iostream>
#include <nlohmann/json.hpp> // a beautiful only-header json toolkit
using default_event_loop = oyoung::event_loop<ev::default_loop, ev::io, ev::async, ev::timer>;
int main(int argc, char **argv)
{
default_event_loop loop{};
auto start = [=](const oyoung::any& argument) {
auto arg = oyoung::any_cast<nlohmann::json> (argument);
std::cout << arg.dump() << std::endl;
};
loop.on("start", start);
loop.on("signal", start);
loop.on("exception", [=] (const oyoung::any& argument) {
auto what = oyoung::any_cast<std::string>(argument);
std::cout << what << std::endl;
});
loop.emit("start", nlohmann::json{ {"name", "SB"} });
return loop.exec();
}
Don't forget to add the "-lev" compile option Note:
- cmake: add "target_link_libraries(target ev) to "CMakeLists.txt file
- Don't forget to add build dependency libev
target_link_libraries(target ev)
example code:
#include <iostream>
#include <oyoung/net.hpp>
#include <nlohmann/json.hpp>
#include <ev++.h>
using default_event_loop = oyoung::event_loop<ev::default_loop, ev::io, ev::async, ev::timer>;
int main(int argc, char *argv[])
{
default_event_loop loop {};
oyoung::net::tcp::default_server server("0.0.0.0", 9090);
server.set_read_event(ev::READ);
server.on("start", [=, &loop](const oyoung::any& arguments) {
auto tuple = oyoung::any_cast<std::tuple<int, int>>(arguments);
loop.start(std::get<0>(tuple), std::get<1>(tuple));
});
server.on("stop", [=, &loop](const oyoung::any& arguments) {
auto descriptor = oyoung::any_cast<int>(arguments);
loop.stop(descriptor);
});
server.on("accept", [=, &loop](const oyoung::any& arguments) {
loop.emit("accept", arguments);
});
server.on("data", [=, &loop](const oyoung::any& arguments) {
loop.emit("data", arguments);
});
server.on("close", [=, &loop](const oyoung::any& arguments) {
loop.emit("close", arguments);
});
loop.on("io", [=, &server](const oyoung::any& arguments) {
server.emit("io", arguments);
});
loop.on("accept", [&](const oyoung::any& argument) {
auto client = oyoung::any_cast<std::shared_ptr<oyoung::net::tcp::default_client>>(argument);
if(client) {
std::cout << client->address() << ": " << client->port() << " connected" << std::endl;
if(server.count() > 1) {
std::cout << "before close, client is good? " << client->good() << std::endl;
client->close();
std::cout << "after close, client is good? " << client->good() << std::endl;
}
}
});
loop.on("data", [](const oyoung::any& argument) {
std::cerr << "on data" << std::endl;
using data_tuple = std::tuple<std::shared_ptr<oyoung::net::tcp::default_client>, std::shared_ptr<oyoung::net::Bytes>>;
auto tuple = oyoung::any_cast<data_tuple>(argument);
auto client = std::get<0>(tuple);
auto bytes = std::get<1>(tuple);
if(bytes) {
std::cout << oyoung::net::String(bytes->begin(), bytes->end()) << std::flush;
client->send(*bytes);
} else {
std::cout << "no data" << std::endl;
}
});
loop.on("close", [](const oyoung::any& argument) {
std::cout << oyoung::any_cast<std::shared_ptr<oyoung::net::tcp::default_client>>(argument)->port() << " closed" << std::endl;
});
loop.on("start", [&](const oyoung::any& argument) {
server.start();
std::cout << "server started" << std::endl;
});
loop.set_interval([&] {
std::cout << "loop is running, client count: " << server.count() << std::endl;
}, std::chrono::seconds(1));
loop.emit("start");
return loop.exec();
}
#include <oyoung/cli.hpp>
#include <iostream>
int main(int argc, char **argv)
{
/* parse command line options*/
oyoung::cli::parse_options options;
/* user arguments*/
options.add("name", "--name", 'N', "default"); // --name=<NAME> OR --name NAME OR -N NAME
options.add("man", "--man", 'M', false); // --man OR -M OR --man=<BOOL> OR --man/-M <BOOL>, <BOOL> may be ON/OFF/on/off/YES/NO/yes/no/T/F
try {
auto result = oyoung::cli::parse(argc, argv, options); // result will be { "name": "...", "man": true/false }
for(const auto& key: result.all_keys()) {
std::cout << key << std::endl;
}
for(const auto& value: result) {
if(value.is_boolean()) {
std::cout << std::boolalpha << oyoung::any_cast<bool >(value) << std::endl;
} else if(value.is_string()) {
std::cout << oyoung::any_cast<std::string>(value) << std::endl;
}
}
} catch (const std::exception& e) {
std::cout << e.what();
}
return 0;
}
#include <oyoung/optional.hpp>
#include <iostream>
int main(int argc, char** argv)
{
oyoung::Int$ n;
oyoung::Dict$<std::string, int> dict;
/* compare with nullptr */
if(n == nullptr) {
std::cout << "N is null" << std::endl;
}
/* assign with operator= */
n = 100;
/* compare with nullptr */
if(nullptr != n) {
/* auto use operator int()*/
std::cout << n << std::endl;
}
/*clear value to null*/
n.clear();
/* use the internal value or the default value given by operator() if null*/
std::cout << n(1000) << std::endl;
/* assign*/
n.assign(101);
if(nullptr != n) {
std::cout << n << std::endl;
}
int a = 0;
/* use let to get value, and condition will be false if value is null */
if(n.let(a)) {
std::cout << a << std::endl;
}
dict()["name"] = 1000;
(*dict)["age"] = 200;
(*dict)["number"] = 30;
for(auto pair: *dict) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
#include <oyoung/format.hpp>
#include <iostream>
int main(int, char**)
{
std::cout << oyoung::format("Hello, world, world, world!!!").replace("world", "C++").to_string() << std::endl;
std::cout <<
oyoung::format("My name is %1, my age is %2, my gender is %3, my height is %4m")
.arg("oyoung")
.arg(26)
.arg("male")
.arg(175.0, 1)
.to_string()
<< std::endl;
std::cout << oyoung::formatter::time_format(std::chrono::system_clock::now(), "%Ec") << std::endl;
std::cout << oyoung::format("Now: %1").arg(std::chrono::system_clock::now(), "%Y-%m-%d %H:%M:%S").to_string() << std::endl;
return 0;
}
property.hpp provides some api of class/struct property, including set, get, willSet, didSet ...
Usage:
#include <oyoung/property.hpp>
#include <iostream>
class Person {
public:
oyoung::property<int> age{1};
oyoung::property<std::string> gender{"Female"};
oyoung::property<std::string> name {};
Person() {
age.willSet([=] (int newVal) {
return newVal > age;
});
age.didSet([=](int val, int old) {
std::cout << "Age changed: ( current: " << val << ", old: " << old << ")" << std::endl;
});
name.bind(_name);
}
std::string& internal_name() { return _name; }
private:
std::string _name {"Noname"};
};
int main(int, char**)
{
Person person;
std::cout << person.internal_name() << ", gender: " << person.gender << ", age: " << person.age << std::endl;
/// assign property stored value
person.age = 26;
person.gender = "Male";
/// assign bind member _name;
person.name = "oyoung";
std::cout << person.internal_name() << ", gender: " << person.gender << ", age: " << person.age << std::endl;
/// assign age will be reject, because 22 less than the old age 26
person.age = 22;
std::cout << person.internal_name() << ", gender: " << person.gender << ", age: " << person.age << std::endl;
return 0;
}
#include <oyoung/locker.hpp>
#include <thread>
#include <iostream>
static int number = 0;
void increasement();
void decreasement();
int main(int, char**) {
std::thread add(increasement);
std::thread minus(decreasement);
add.join();
minus.join();
}
void increasement() {
int loop {100};
while (loop --> 0) {
lock("number") [=] {
std::cout << "[+] after increase: " << ++number << std::endl;
};
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
void decreasement() {
do {
std::this_thread::sleep_for(std::chrono::seconds(1));
lock("number") [=] {
std::cout << "[-] after decrease: " << --number << std::endl;
};
} while (number > 0);
}
#include <oyoung/range.hpp>
#include <iostream>
int main(int , char **) {
std::cout << "range(9): ";
for(auto i: oyoung::range(9)) {
std::cout << i << " ";
}
std::cout << std::endl;
std::cout << "range(1, 10): ";
for(auto i: oyoung::range(1, 10)) {
std::cout << i << " ";
}
std::cout << std::endl;
std::cout << "range(20, 10): ";
for(auto i: oyoung::range(20, 10)) {
std::cout << i << " ";
}
std::cout << std::endl;
std::cout << "range(1, 10, step: 3): ";
for(auto i: oyoung::range(1, 10, 3)) {
std::cout << i << " ";
}
std::cout << std::endl;
std::cout << "range(20, 10, step: 2): ";
for(auto i: oyoung::range(20, 10, 2)) {
std::cout << i << " ";
}
std::cout << std::endl;
repeat(5) [](int i) {
std::cout << "repeat(i) " << i << " time" << std::endl;
};
int times = 0;
repeat(3) [&] {
std::cout << "repeat " << times++ << std::endl;
};
oyoung::Repeater(6) << [](int i) {
std::cout << "oyoung::Repeater: " << i << std::endl;
};
return 0;
}
#include <oyoung/topic.hpp>
#include <iostream>
int main(int,char**) {
oyoung::topic::subscribe<bool>("success", [](bool success) {
std::cout << "success: " << success << std::endl;
});
/// ...
/// some failure
oyoung::topic::publish("success", false);
/// success
oyoung::topic::publish("success", true);
return 0;
}