add adlshfks

This commit is contained in:
Bartosz Wieczorek 2018-06-08 14:00:28 +02:00
parent 7d4462b3cc
commit 9f2e2d4492

View File

@ -10,6 +10,216 @@
#include <Wt/WEnvironment.h>
#include <chaiscript/chaiscript.hpp>
#include <dlfcn.h>
#include <stdio.h>
#include <cstdio>
#include <functional>
#include <type_traits>
#include <vector>
#include <boost/hana.hpp>
#include <boost/hana/ext/std/tuple.hpp>
template < typename Iter >
void join(Iter begin, Iter end, std::string const & separator, std::string & result) {
if(begin != end)
result += std::string{"'"} + *begin++ + "'";
while(begin != end)
result += separator + "'" + *begin++ + "'";
}
void explode() {
std::string name{"Reflect"};
std::string out;
out.reserve(10 + name.size() * 4);
out += "Name<";
join(name.begin(), name.end(), ",", out);
out += ">";
puts(out.c_str());
}
struct Reflect {
Reflect() {}
Reflect(int) {}
virtual ~Reflect() = default;
virtual void foo() {
puts("FOO\n");
}
void foo() const {
puts("const FOO\n");
}
void bar() {
puts("BAR\n");
}
void bar() const {
puts("const BAR\n");
}
int doSomething() {
return 5;
}
};
struct AndThis {
void baz() {
puts("BAZ\n");
}
};
namespace meta {
template < typename Class >
struct reflection : public std::false_type {};
namespace api {
enum class entity_type { //
CppClass,
CppClassCtor,
CppClassMethod
};
template < typename Meta >
constexpr auto name(const Meta & m) {
using namespace boost::hana::literals;
return m.name();
}
template < typename Meta >
constexpr auto fn(const Meta & m) {
return m._fn;
}
template <typename Meta >
constexpr auto is_virtual(const Meta &m){
return m.is_virtual();
}
template < typename Entities, typename Visitor >
void visit(Entities && entities, Visitor && visitor) {
boost::hana::for_each(entities, visitor);
}
template < typename Meta >
struct ctor_t {
using type = typename Meta::signature;
};
} // namespace api
namespace {
template < char... s >
constexpr char const string_storage[sizeof...(s) + 1] = {s..., '\0'};
}
namespace details {
template < api::entity_type type_ >
struct CppEntity {
static constexpr api::entity_type value{type_};
static constexpr auto type() {
return value;
}
};
} // namespace details
template < char... name_ >
struct Name {
static constexpr const char * name() {
return &string_storage< name_... >[0];
}
};
template < typename Name, typename Signature, bool Virtual >
struct MetaMethod : public Name, public details::CppEntity< api::entity_type::CppClassMethod > {
using signature = Signature;
signature _fn;
static constexpr bool is_virtual() {
return Virtual;
};
constexpr MetaMethod(Signature fn) : _fn{fn} {}
};
template < typename Name, typename Signature >
struct MetaCtor : public Name, public details::CppEntity< api::entity_type::CppClassCtor > {
using signature = Signature;
};
template < typename Name >
struct MetaClass : public Name, public details::CppEntity< api::entity_type::CppClass > {};
template <>
struct reflection< Reflect > : public std::true_type {
static constexpr auto methods() {
return std::make_tuple( //
MetaMethod< Name< 'f', 'o', 'o' >, void (Reflect::*)(), true >(&Reflect::foo), //
MetaMethod< Name< 'f', 'o', 'o' >, void (Reflect::*)() const, false >(&Reflect::foo), //
MetaMethod< Name< 'b', 'a', 'r' >, void (Reflect::*)(), false >(&Reflect::bar), //
MetaMethod< Name< 'b', 'a', 'r' >, void (Reflect::*)() const, false >(&Reflect::bar) //
);
}
static constexpr auto ctors() {
return std::make_tuple( //
MetaCtor< Name< 'R', 'e', 'f', 'l', 'e', 'c', 't' >, Reflect() >(), //
MetaCtor< Name< 'R', 'e', 'f', 'l', 'e', 'c', 't' >, Reflect(int) >() //
);
}
static constexpr auto class_info() {
return std::make_tuple(MetaClass< Name< 'R', 'e', 'f', 'l', 'e', 'c', 't' > >());
}
static constexpr auto all() {
return std::tuple_cat(class_info(), ctors(), methods());
}
};
} // namespace meta
enum class TestEnum{one,two};
int bootstrap() {
chaiscript::ChaiScript chai;
meta::api::visit(meta::reflection< Reflect >::all(), [&chai](const auto entity) {
if constexpr(entity.type() == meta::api::entity_type::CppClassMethod) {
puts("got method");
if constexpr (meta::api::is_virtual(entity)){
puts(" virtual");
}
chai.add(chaiscript::fun(meta::api::fn(entity)), meta::api::name(entity));
} else if constexpr(entity.type() == meta::api::entity_type::CppClassCtor) {
puts("got ctor");
chai.add(chaiscript::constructor< typename meta::api::ctor_t< decltype(entity) >::type >(), meta::api::name(entity));
} else if constexpr(entity.type() == meta::api::entity_type::CppClass) {
puts("got class");
chai.add(chaiscript::user_type< Reflect >(), meta::api::name(entity));
}
});
using namespace std::string_literals;
chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
chaiscript::utility::add_class< TestEnum >(
*m, "EnumTest"s, std::vector{std::pair{TestEnum::one, "one"s}, std::pair{TestEnum::two, "two"s}});
chai.eval(R"(
var test = Reflect()
test.foo()
test.bar()
)");
explode();
return 0;
// return example_main(argc, argv, {}, &print_ast);
}
static auto _createSinks() {
std::vector< spdlog::sink_ptr > sinks;
auto stdout_sink = spdlog::sinks::stdout_sink_mt::instance();
@ -41,8 +251,8 @@ static auto createDbConnection(std::function< bool(const std::string &, std::str
}
}
std::unique_ptr< Wt::WApplication >createApplication (const Wt::WEnvironment &env) {
auto server = env.server();
std::unique_ptr< Wt::WApplication > createApplication(const Wt::WEnvironment & env) {
auto server = env.server();
auto connection = createDbConnection([server](const auto & name, auto & val) { //
return server->readConfigurationProperty(name, val);
});
@ -53,9 +263,10 @@ std::unique_ptr< Wt::WApplication >createApplication (const Wt::WEnvironment &en
}
int main(int argc, char ** argv) {
initializeLogs();
eedb::WebServer server{argc, argv};
bootstrap();
// initializeLogs();
// eedb::WebServer server{argc, argv};
server.run(createApplication);
// server.run(createApplication);
return 0;
}