summaryrefslogtreecommitdiff
path: root/c++/tools/c_gen_iface.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'c++/tools/c_gen_iface.hpp')
-rw-r--r--c++/tools/c_gen_iface.hpp240
1 files changed, 240 insertions, 0 deletions
diff --git a/c++/tools/c_gen_iface.hpp b/c++/tools/c_gen_iface.hpp
new file mode 100644
index 0000000..867fe60
--- /dev/null
+++ b/c++/tools/c_gen_iface.hpp
@@ -0,0 +1,240 @@
+#include <forstio/core/error.h>
+#include <forstio/codec/schema.h>
+
+#include <string>
+#include <sstream>
+#include <map>
+
+#include <iostream>
+
+namespace saw {
+
+namespace impl {
+
+template<typename Schema>
+struct c_primitive_string {
+ static_assert(always_false<Schema>, "Not supported");
+};
+
+template<>
+struct c_primitive_string<schema::Int8> {
+ static constexpr std::string_view value = "int8_t";
+};
+
+template<>
+struct c_primitive_string<schema::Int16> {
+ static constexpr std::string_view value = "int16_t";
+};
+
+template<>
+struct c_primitive_string<schema::Int32> {
+ static constexpr std::string_view value = "int32_t";
+};
+
+template<>
+struct c_primitive_string<schema::Int64> {
+ static constexpr std::string_view value = "int64_t";
+};
+
+template<>
+struct c_primitive_string<schema::UInt8> {
+ static constexpr std::string_view value = "uint8_t";
+};
+
+template<>
+struct c_primitive_string<schema::UInt16> {
+ static constexpr std::string_view value = "uint16_t";
+};
+
+template<>
+struct c_primitive_string<schema::UInt32> {
+ static constexpr std::string_view value = "uint32_t";
+};
+
+template<>
+struct c_primitive_string<schema::UInt64> {
+ static constexpr std::string_view value = "uint64_t";
+};
+
+template<>
+struct c_primitive_string<schema::Float32> {
+ static constexpr std::string_view value = "float";
+};
+
+template<>
+struct c_primitive_string<schema::Float64> {
+ static constexpr std::string_view value = "double";
+};
+
+template<typename Schema>
+struct c_data_translater {
+ static_assert(always_false<Schema>, "Not supported");
+};
+
+template<typename T, size_t N>
+struct c_data_translater<schema::Primitive<T,N>> {
+ using Schema = schema::Primitive<T,N>;
+ static error_or<void> generate(std::map<std::string,std::string>& map_str, std::string& str, const std::string& prefix){
+ str += c_primitive_string<Schema>::value;
+ return void_t{};
+ }
+};
+
+template<typename T, size_t Dim>
+struct c_data_translater<schema::Array<T,Dim>> {
+ static error_or<void> generate(std::map<std::string, std::string>& map_str, std::string& type_str, const std::string& prefix){
+ type_str = prefix + "_";
+ type_str += "array_";
+
+ std::string inner_type_str;
+ auto eov = impl::c_data_translater<T>::generate(map_str, inner_type_str, prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+
+ type_str += inner_type_str;
+
+ if(Dim > 1){
+ type_str += "_";
+ type_str += std::to_string(Dim);
+ type_str += "d";
+ }
+
+ if(map_str.find(type_str) != map_str.end()){
+ return void_t{};
+ }
+
+ std::string str = "struct ";
+ str += type_str;
+
+ str += " {\n";
+
+ str += "\t" + inner_type_str + "* data;\n";
+ str += "\tsize_t size;\n";
+ if( Dim > 1 ){
+ str += "\tsize_t dims["+std::to_string(Dim)+"];\n";
+ }
+
+ str += "};\n";
+
+ map_str.insert(std::make_pair(std::move(type_str), std::move(str)));
+ return void_t{};
+ }
+};
+
+template<typename Interface>
+struct c_rpc_translater {
+ static_assert(always_false<Interface>,"Not supported");
+};
+
+template<class Request, class Response>
+struct c_rpc_translater<schema::Function<Request, Response>> {
+ using Map = std::map<std::string, std::string>;
+
+ static error_or<void> generate(const std::string& prefix, Map& type_map, Map& func_map){
+
+ return void_t{};
+ }
+};
+
+template<class... Requests, class... Responses, string_literal... Names>
+struct c_rpc_translater<schema::Interface<schema::Member<schema::Function<Requests, Responses>, Names>...>> {
+ using Map = std::map<std::string, std::string>;
+
+ template<size_t i>
+ static error_or<void> generate_member(const std::string& prefix, Map& type_map, Map& func_map){
+ using Req = typename parameter_pack_type<i,Requests...>::type;
+ using Resp = typename parameter_pack_type<i,Responses...>::type;
+ constexpr string_literal lit = parameter_key_pack_type<i, Names...>::literal;
+
+ std::string func_name{lit.view()};
+ if(func_map.find(func_name) != func_map.end()){
+ return make_error<err::already_exists>();
+ }
+
+ {
+ std::string type_str;
+ auto eov = c_rpc_translater<schema::Function<Req, Resp>>::generate(prefix, type_map, func_map);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ if constexpr ((i+1) < sizeof...(Requests) ){
+ return generate_member<i+1>(prefix, type_map, func_map);
+ }
+ return void_t{};
+ }
+
+ static error_or<void> generate(const std::string& prefix){
+ Map type_map, func_map;
+
+ if constexpr ( sizeof...(Requests) > 0 ){
+ return generate_member<0>(prefix, type_map, func_map);
+ }
+
+ return void_t{};
+ }
+};
+}
+
+template<typename Interface>
+error_or<std::string> generate_c_rpc_interface(){
+ std::stringstream iss;
+ auto eov = impl::c_rpc_translater<Interface>::generate(iss, "c_saw");
+
+ if(eov.is_error()){
+ return std::move(eov.get_error());
+ }
+
+ try {
+ return iss.str();
+ }catch(const std::exception& e){
+ // Do nothing for now
+ }
+ return make_error<err::out_of_memory>();
+}
+
+error_or<void> generate_array_example(){
+ using Schema = schema::Array<schema::Int32,2>;
+
+ using Schema2 = schema::Array<schema::Float64,5>;
+
+ using Schema3 = schema::Array<schema::UInt16,1>;
+
+ std::string prefix = "c_saw";
+ std::map<std::string,std::string> map_str;
+ {
+ std::string type_str;
+ auto eov = impl::c_data_translater<Schema>::generate(map_str, type_str, prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ std::string type_str;
+ auto eov = impl::c_data_translater<Schema2>::generate(map_str, type_str, prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ std::string type_str;
+ auto eov = impl::c_data_translater<Schema3>::generate(map_str, type_str, prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ std::cout<<"Prefix: "<<prefix<<std::endl;
+
+ for(auto& iter : map_str){
+ std::cout<<"\nType: \""<<iter.first<<"\""<<std::endl;
+ std::cout<<"Definition:\n\"\"\"\n";
+ std::cout<<iter.second;
+ std::cout<<"\"\"\""<<std::endl;
+ }
+
+ return void_t{};
+}
+}