From cad3d1068e004f7f4e2960e642a15750cf4d9be8 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Sun, 15 Feb 2015 10:41:34 +0100 Subject: [PATCH 01/94] Refactor di so instantiate methods can throw. --- iod/di.hh | 130 ++++++++++++---------------------------------------- tests/di.cc | 14 +++--- 2 files changed, 36 insertions(+), 108 deletions(-) diff --git a/iod/di.hh b/iod/di.hh index 29d1778..691a6b2 100644 --- a/iod/di.hh +++ b/iod/di.hh @@ -162,23 +162,30 @@ namespace iod typedef not_found type; }; + template + using di_factory_return_t = std::remove_reference_t::instantiate)>>; + template struct find_di_factory_iterator, I, - std::enable_if_t::instantiate)> >, - I>::value> > + std::enable_if_t, I>::value> > : public find_di_factory_iterator, I> {}; template struct find_di_factory_iterator, I, - std::enable_if_t::instantiate)> >, - I>::value> > + std::enable_if_t, I>::value> > { typedef T type; }; + template + struct find_di_factory_iterator, I, + std::enable_if_t>::value> > + : public find_di_factory_iterator, I> + {}; + template - using find_di_factory_t = std::remove_reference_t::type>; + using find_di_factory_t = std::remove_reference_t>::type>; // Provide an element of type E: // If \to_inject contains an element of type E, return it. @@ -193,10 +200,6 @@ namespace iod typedef std::remove_reference_t T2; typedef std::remove_const_t> E2; - //dummy_t x = tuple_get_by_type(to_inject); - //std::string& x = (E*)0; - //void* x= std::string(); - //void* x = to_inject; return static_if::value or tuple_embeds::value or tuple_embeds::value @@ -210,7 +213,6 @@ namespace iod [&] (auto& to_inject) -> decltype(auto) { typedef find_di_factory_t FT; - return iod::static_if::value>( // If to_inject embed a factory, call it. [&] (auto&& deps, auto* e, auto* ft_) -> auto { @@ -274,6 +276,7 @@ namespace iod return create_di_ctx_iterator::template run(d); } }; + // Instantiate the injection list from the types A... // returns the concatenation of ctx, elements of type A... and // the elements required to build them. @@ -298,94 +301,31 @@ namespace iod }); } - template - decltype(auto) create_di_ctx(std::enable_if_t*, - std::tuple*, U&&... args) - { - return std::tuple(std::forward(args)...); - }; - - template - decltype(auto) create_di_ctx(std::enable_if_t<(sizeof...(T) > sizeof...(U))>*, - std::tuple* ctx, U&&... args) - { - return create_di_ctx(0, ctx, std::forward(args)..., - instantiate>> - (std::forward_as_tuple(args...))); - }; - - template - struct static_array - { - unsigned char data[N]; - }; - - template - decltype(auto) create_di_ctx2(std::enable_if_t<(N == sizeof...(T))>*, - std::tuple& ctx, U&&... args) - { - }; - - - template - auto sub_tuple(std::enable_if_t<(N == 0)>*, - std::tuple&& t, T&...) + template + decltype(auto) create_stack_and_call(std::tuple<>*, + std::tuple*, + F fun, B&&... to_inject) { - return t; + return fun(tuple_get_by_type(std::forward_as_tuple(to_inject...))...); } - - template - auto sub_tuple(std::enable_if_t<(N > 0)>*, - std::tuple&& t, T1& t1, T&... args) - { - return sub_tuple(0, std::tuple_cat(t, std::forward_as_tuple(t1)), args...); + + template + decltype(auto) create_stack_and_call(std::tuple*, + std::tuple* args, + F fun, B&&... to_inject) + { + return create_stack_and_call((std::tuple*)0, args, fun, + std::forward(to_inject)..., + instantiate(std::forward_as_tuple(to_inject...))); + } - template - decltype(auto) create_di_ctx2(std::enable_if_t<(N < sizeof...(T))>*, - std::tuple& ctx, U&&... args) - { - typedef std::remove_reference_t(ctx))> X; - new (&std::get(ctx)) X(instantiate>> - (std::tuple_cat(std::forward_as_tuple(args...), - //std::forward_as_tuple(tuple_get_by_type(ctx)...) - sub_tuple(0, std::make_tuple(), tuple_get_by_type(ctx)...) - ))); - create_di_ctx2(0, ctx, std::forward(args)...); - }; - template - decltype(auto) get_from_ctx_or_args(std::tuple& ctx, B&&... to_inject) - { - return tuple_get_by_type( - std::tuple_cat(std::forward_as_tuple(tuple_get_by_type(ctx)...), - std::forward_as_tuple(to_inject...)) - ); - } - - template - struct desctructor_caller - { - desctructor_caller(F f) : f_(f) {} - ~desctructor_caller() { f_(); } - F f_; - }; - - template - auto make_destructor_caller(F f) - { - return desctructor_caller(f); - } - // Call fun with its required argument A... // by picking in args... or calling A::instantiate() template - auto call_with_di2(F fun, std::tuple*, B&&... to_inject) + auto call_with_di2(F fun, std::tuple* arguments, B&&... to_inject) { - - // function arguments type. - callable_arguments_tuple_t* arguments; - // Compute the context type containing the arguments plus the // dependencies of the possible A::instantiate(...) methods. typedef @@ -398,18 +338,8 @@ namespace iod // Remove the rvalues references to be able to store the context. typedef tuple_remove_rvalues_t ctx_type2; typedef tuple_filter_references_t ctx_type3; - // Instantiate it. - static_array ctx_buffer; - ctx_type3& ctx = *(ctx_type3*) &ctx_buffer; - - // Destroy it at the end of the scope. - auto x = make_destructor_caller([&] () { ctx.~ctx_type3(); }); - - // Create the needed dependencies: - create_di_ctx2<0>(0, ctx, std::forward(to_inject)...); - // Call the function. - return fun(get_from_ctx_or_args(ctx, std::forward(to_inject)...)...); + return create_stack_and_call((ctx_type3*)0, (std::tuple*)0, fun, to_inject...); } } diff --git a/tests/di.cc b/tests/di.cc index bdbbfdc..52d040b 100644 --- a/tests/di.cc +++ b/tests/di.cc @@ -38,12 +38,13 @@ struct D_factory { D_factory() {} - D instantiate() + D& instantiate() { std::cout << " instantiate D" << std::endl; - return D(); + return d; } + D d; }; struct NC @@ -185,11 +186,11 @@ int main() iod::di_call(fun6, 2.f); iod::di_call(fun7); - // Check if no copy happend. + //Check if no copy happend. NC nc; iod::di_call(fun8, nc); - - auto f = [] (int x, float y) {}; + + auto f = [] (int x, float f) {}; int_factory int_f; float_factory float_f; iod::di_call(f, int_f, float_f); @@ -199,7 +200,4 @@ int main() iod::di_call(fun9, with_data{"toto"}); iod::di_call(fun10, with_data{"toto"}); - - - //void* xx = iod::return_factory_type(0); } From 13b30dc0f2c42d58a2d1301302465f898769473b Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Sun, 15 Feb 2015 11:55:38 +0100 Subject: [PATCH 02/94] Add an automatic symbols generator --- tools/CMakeLists.txt | 3 + tools/iod_generate_symbols.cc | 101 ++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 tools/iod_generate_symbols.cc diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 6b2edc8..dc68240 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -7,6 +7,9 @@ add_definitions(-std=c++14) add_executable(iodc iod_compiler.cc) target_link_libraries(iodc boost_regex) +add_executable(iod_generate_symbols iod_generate_symbols.cc) +target_link_libraries(iod_generate_symbols boost_regex) + install(TARGETS iodc EXPORT IodTargets DESTINATION bin) diff --git a/tools/iod_generate_symbols.cc b/tools/iod_generate_symbols.cc new file mode 100644 index 0000000..d4bacda --- /dev/null +++ b/tools/iod_generate_symbols.cc @@ -0,0 +1,101 @@ +#include +#include +#include +#include + +std::string symbol_definition(std::string s); + +// Iod symbols generator. +// +// For each variable name starting with underscore, generates a symbol +// definition. +// +int main(int argc, char* argv[]) +{ + using namespace std; + + if (argc < 3) + { + cout << "Usage: " << argv[0] << " input_cpp_file1, ..., input_cpp_fileN, output_cpp_header_file" << endl; + return 1; + } + + set symbols; + boost::regex symbol_regex("_([[:alnum:]_]+)"); + + auto parse_file = [&] (std::string filename) { + + ifstream f(filename); + if (!f) + { + std::cerr << "Cannot open file " << argv[1] << " for reading." << std::endl; + } + + std::string line; + bool in_raw_string = false; + while (!f.eof()) + { + getline(f, line); + + std::vector dbl_quotes_pos; + bool escaped = false; + for (int i = 0; i < line.size(); i++) + { + if (line[i] == '"' and !escaped) dbl_quotes_pos.push_back(i); + else if (line[i] == '\\') escaped = !escaped; + else escaped = false; + } + + auto is_in_string = [&] (int p) { + int i = 0; + while (i < dbl_quotes_pos.size() and dbl_quotes_pos[i] <= p) i++; + return i % 2; + }; + + std::string::const_iterator start, end; + start = line.begin(); + end = line.end(); + boost::match_results what; + boost::match_flag_type flags = boost::match_default; + while(regex_search(start, end, what, symbol_regex, flags)) + { + std::cout << what[1] << std::endl; + if (!is_in_string(what.position())) + symbols.insert(what[1]); + start = what[0].second; + } + + } + }; + + for (int i = 1; i < argc - 1; i++) + parse_file(argv[i]); + + std::ofstream os(argv[argc - 1]); + if (!os) + { + std::cerr << "Cannot open file " << argv[2] << " for writing." << std::endl; + return 2; + } + + os << "// Generated by iod_generate_symbols." << endl; + std::stringstream symbols_content; + os << "#include " << endl; + for (string s : symbols) + { + os << symbol_definition(s) << endl; + } +} + +std::string symbol_definition(std::string s) +{ + std::string body = R"cpp(#ifndef IOD_SYMBOL____S__ +#define IOD_SYMBOL____S__ + iod_define_symbol(__S__, ___S__) +#endif +)cpp"; + + boost::regex s_regex("__S__"); + body = boost::regex_replace(body, s_regex, s); + return body; +} From b579716f718c3337b09574be517c99fd9c47f344 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Sun, 15 Feb 2015 12:22:40 +0100 Subject: [PATCH 03/94] Finish the new symbol generator. --- iod/number_symbol_definitions.hh | 74 +++++++++++++++----------------- iod/symbol.hh | 8 ++-- tools/iod_generate_symbols.cc | 28 +++++++++--- 3 files changed, 61 insertions(+), 49 deletions(-) diff --git a/iod/number_symbol_definitions.hh b/iod/number_symbol_definitions.hh index bb364c6..0e3b0a2 100644 --- a/iod/number_symbol_definitions.hh +++ b/iod/number_symbol_definitions.hh @@ -1,72 +1,68 @@ -// Convert the symbol file into a C++ header using sed, or another text processing tool -// with the equivalent command: -// sed -e 's/^\([a-zA-Z1-9_]\+\)/#ifndef IOD_SYMBOL__\1\n#define IOD_SYMBOL__\1\n iod_define_number_symbol(\1)\n#endif/' numbers.sb > number_symbol_definitions.hh - -#ifndef IOD_SYMBOL__1 -#define IOD_SYMBOL__1 +#ifndef IOD_SYMBOL_1 +#define IOD_SYMBOL_1 iod_define_number_symbol(1) #endif -#ifndef IOD_SYMBOL__2 -#define IOD_SYMBOL__2 +#ifndef IOD_SYMBOL_2 +#define IOD_SYMBOL_2 iod_define_number_symbol(2) #endif -#ifndef IOD_SYMBOL__3 -#define IOD_SYMBOL__3 +#ifndef IOD_SYMBOL_3 +#define IOD_SYMBOL_3 iod_define_number_symbol(3) #endif -#ifndef IOD_SYMBOL__4 -#define IOD_SYMBOL__4 +#ifndef IOD_SYMBOL_4 +#define IOD_SYMBOL_4 iod_define_number_symbol(4) #endif -#ifndef IOD_SYMBOL__5 -#define IOD_SYMBOL__5 +#ifndef IOD_SYMBOL_5 +#define IOD_SYMBOL_5 iod_define_number_symbol(5) #endif -#ifndef IOD_SYMBOL__6 -#define IOD_SYMBOL__6 +#ifndef IOD_SYMBOL_6 +#define IOD_SYMBOL_6 iod_define_number_symbol(6) #endif -#ifndef IOD_SYMBOL__7 -#define IOD_SYMBOL__7 +#ifndef IOD_SYMBOL_7 +#define IOD_SYMBOL_7 iod_define_number_symbol(7) #endif -#ifndef IOD_SYMBOL__8 -#define IOD_SYMBOL__8 +#ifndef IOD_SYMBOL_8 +#define IOD_SYMBOL_8 iod_define_number_symbol(8) #endif -#ifndef IOD_SYMBOL__9 -#define IOD_SYMBOL__9 +#ifndef IOD_SYMBOL_9 +#define IOD_SYMBOL_9 iod_define_number_symbol(9) #endif -#ifndef IOD_SYMBOL__9 -#define IOD_SYMBOL__9 +#ifndef IOD_SYMBOL_9 +#define IOD_SYMBOL_9 iod_define_number_symbol(9) #endif -#ifndef IOD_SYMBOL__10 -#define IOD_SYMBOL__10 +#ifndef IOD_SYMBOL_10 +#define IOD_SYMBOL_10 iod_define_number_symbol(10) #endif -#ifndef IOD_SYMBOL__11 -#define IOD_SYMBOL__11 +#ifndef IOD_SYMBOL_11 +#define IOD_SYMBOL_11 iod_define_number_symbol(11) #endif -#ifndef IOD_SYMBOL__12 -#define IOD_SYMBOL__12 +#ifndef IOD_SYMBOL_12 +#define IOD_SYMBOL_12 iod_define_number_symbol(12) #endif -#ifndef IOD_SYMBOL__13 -#define IOD_SYMBOL__13 +#ifndef IOD_SYMBOL_13 +#define IOD_SYMBOL_13 iod_define_number_symbol(13) #endif -#ifndef IOD_SYMBOL__14 -#define IOD_SYMBOL__14 +#ifndef IOD_SYMBOL_14 +#define IOD_SYMBOL_14 iod_define_number_symbol(14) #endif -#ifndef IOD_SYMBOL__15 -#define IOD_SYMBOL__15 +#ifndef IOD_SYMBOL_15 +#define IOD_SYMBOL_15 iod_define_number_symbol(15) #endif -#ifndef IOD_SYMBOL__16 -#define IOD_SYMBOL__16 +#ifndef IOD_SYMBOL_16 +#define IOD_SYMBOL_16 iod_define_number_symbol(16) -#endif \ No newline at end of file +#endif diff --git a/iod/symbol.hh b/iod/symbol.hh index 9abcd20..89df796 100644 --- a/iod/symbol.hh +++ b/iod/symbol.hh @@ -59,13 +59,13 @@ namespace iod value_type SYMBOL; \ }; -#define iod_define_symbol(SYMBOL, NAME) \ +#define iod_define_symbol(SYMBOL) \ namespace s { \ - struct NAME##_t : iod::symbol \ + struct _##SYMBOL##_t : iod::symbol<_##SYMBOL##_t> \ { \ - iod_define_symbol_body(SYMBOL, NAME) \ + iod_define_symbol_body(SYMBOL, _##SYMBOL) \ }; \ - constexpr NAME##_t NAME; \ + constexpr _##SYMBOL##_t _##SYMBOL; \ } template diff --git a/tools/iod_generate_symbols.cc b/tools/iod_generate_symbols.cc index d4bacda..e4682cf 100644 --- a/tools/iod_generate_symbols.cc +++ b/tools/iod_generate_symbols.cc @@ -21,7 +21,7 @@ int main(int argc, char* argv[]) } set symbols; - boost::regex symbol_regex("_([[:alnum:]_]+)"); + boost::regex symbol_regex(".?_([[:alnum:]_]+)"); auto parse_file = [&] (std::string filename) { @@ -59,8 +59,11 @@ int main(int argc, char* argv[]) boost::match_flag_type flags = boost::match_default; while(regex_search(start, end, what, symbol_regex, flags)) { - std::cout << what[1] << std::endl; - if (!is_in_string(what.position())) + std::string m = what[0]; + std::string s = what[1]; + + bool is_type = s.size() >= 2 and s[s.size() - 2] == '_' and s[s.size() - 1] == 't'; + if (!std::isalnum(m[0]) and !is_in_string(what.position()) and !is_type) symbols.insert(what[1]); start = what[0].second; } @@ -89,9 +92,22 @@ int main(int argc, char* argv[]) std::string symbol_definition(std::string s) { - std::string body = R"cpp(#ifndef IOD_SYMBOL____S__ -#define IOD_SYMBOL____S__ - iod_define_symbol(__S__, ___S__) + std::string body; + if (std::isdigit(s[0])) + { + body = R"cpp(#ifndef IOD_SYMBOL___S__ +#define IOD_SYMBOL___S__ + iod_define_number_symbol(__S__) +#endif +)cpp"; + // Check the string is actually a number. + for (int i = 0; i < s.size(); i++) + if (!std::isdigit(s[i])) return ""; + } + else + body = R"cpp(#ifndef IOD_SYMBOL___S__ +#define IOD_SYMBOL___S__ + iod_define_symbol(__S__) #endif )cpp"; From 91a7f68210c150e7d89d068baa79e3eb2d37552d Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Sun, 15 Feb 2015 12:34:54 +0100 Subject: [PATCH 04/94] Fix iod_generated_symbol. Do not generate symbols in the keywords list. --- iod/symbol_definitions.hh | 238 +++++++++++++++++++++------------- tests/readme.cc | 6 +- tests/symbols.hh | 117 ++++++++++++----- tests/symbols.sb | 10 -- tools/iod_generate_symbols.cc | 7 +- 5 files changed, 246 insertions(+), 132 deletions(-) delete mode 100644 tests/symbols.sb diff --git a/iod/symbol_definitions.hh b/iod/symbol_definitions.hh index 4489193..065abe0 100644 --- a/iod/symbol_definitions.hh +++ b/iod/symbol_definitions.hh @@ -1,118 +1,182 @@ -// Convert the symbol file into a C++ header using sed, or another text processing tool -// with the equivalent command: -// sed -e 's/^\([a-zA-Z1-9_]\)\([a-zA-Z1-9_]*\)/#ifndef IOD_SYMBOL__\U\1\L\2\n\#define IOD_SYMBOL__\U\1\L\2\n iod_define_symbol(\1\2, _\U\1\L\2)\n#endif/' symbols.sb > symbol_definitions.hh +// Generated by iod_generate_symbols. +#include +#ifndef IOD_SYMBOL_1 +#define IOD_SYMBOL_1 + iod_define_number_symbol(1) +#endif -#ifndef IOD_SYMBOL__select -#define IOD_SYMBOL__select - iod_define_symbol(select, _select) +#ifndef IOD_SYMBOL_2 +#define IOD_SYMBOL_2 + iod_define_number_symbol(2) #endif -#ifndef IOD_SYMBOL__update -#define IOD_SYMBOL__update - iod_define_symbol(update, _update) + +#ifndef IOD_SYMBOL__compiler_insert_symbols_here__ +#define IOD_SYMBOL__compiler_insert_symbols_here__ + iod_define_symbol(_compiler_insert_symbols_here__) #endif -#ifndef IOD_SYMBOL__insert -#define IOD_SYMBOL__insert - iod_define_symbol(insert, _insert) + +#ifndef IOD_SYMBOL_as +#define IOD_SYMBOL_as + iod_define_symbol(as) #endif -#ifndef IOD_SYMBOL__delete_ -#define IOD_SYMBOL__delete_ - iod_define_symbol(delete_, _delete_) + +#ifndef IOD_SYMBOL_attribute +#define IOD_SYMBOL_attribute + iod_define_symbol(attribute) #endif -#ifndef IOD_SYMBOL__where -#define IOD_SYMBOL__where - iod_define_symbol(where, _where) + +#ifndef IOD_SYMBOL_attribute_ +#define IOD_SYMBOL_attribute_ + iod_define_symbol(attribute_) #endif -#ifndef IOD_SYMBOL__order_by -#define IOD_SYMBOL__order_by - iod_define_symbol(order_by, _order_by) + +#ifndef IOD_SYMBOL_avg +#define IOD_SYMBOL_avg + iod_define_symbol(avg) #endif -#ifndef IOD_SYMBOL__from -#define IOD_SYMBOL__from - iod_define_symbol(from, _from) + +#ifndef IOD_SYMBOL_compiler_insert_symbols_here__ +#define IOD_SYMBOL_compiler_insert_symbols_here__ + iod_define_symbol(compiler_insert_symbols_here__) #endif -#ifndef IOD_SYMBOL__table -#define IOD_SYMBOL__table - iod_define_symbol(table, _table) + +#ifndef IOD_SYMBOL_condition +#define IOD_SYMBOL_condition + iod_define_symbol(condition) #endif -#ifndef IOD_SYMBOL__order -#define IOD_SYMBOL__order - iod_define_symbol(order, _order) + +#ifndef IOD_SYMBOL_cpt +#define IOD_SYMBOL_cpt + iod_define_symbol(cpt) #endif -#ifndef IOD_SYMBOL__set -#define IOD_SYMBOL__set - iod_define_symbol(set, _set) + +#ifndef IOD_SYMBOL_criteria +#define IOD_SYMBOL_criteria + iod_define_symbol(criteria) #endif -#ifndef IOD_SYMBOL__into -#define IOD_SYMBOL__into - iod_define_symbol(into, _into) + +#ifndef IOD_SYMBOL_elt +#define IOD_SYMBOL_elt + iod_define_symbol(elt) #endif -#ifndef IOD_SYMBOL__values -#define IOD_SYMBOL__values - iod_define_symbol(values, _values) + +#ifndef IOD_SYMBOL_empty +#define IOD_SYMBOL_empty + iod_define_symbol(empty) #endif -#ifndef IOD_SYMBOL__join -#define IOD_SYMBOL__join - iod_define_symbol(join, _join) + +#ifndef IOD_SYMBOL_exp +#define IOD_SYMBOL_exp + iod_define_symbol(exp) #endif -#ifndef IOD_SYMBOL__inner_join -#define IOD_SYMBOL__inner_join - iod_define_symbol(inner_join, _inner_join) + +#ifndef IOD_SYMBOL_from +#define IOD_SYMBOL_from + iod_define_symbol(from) #endif -#ifndef IOD_SYMBOL__group_by -#define IOD_SYMBOL__group_by - iod_define_symbol(group_by, _group_by) + +#ifndef IOD_SYMBOL_group_by +#define IOD_SYMBOL_group_by + iod_define_symbol(group_by) #endif -#ifndef IOD_SYMBOL__on -#define IOD_SYMBOL__on - iod_define_symbol(on, _on) + +#ifndef IOD_SYMBOL_has +#define IOD_SYMBOL_has + iod_define_symbol(has) #endif -#ifndef IOD_SYMBOL__condition -#define IOD_SYMBOL__condition - iod_define_symbol(condition, _condition) + +#ifndef IOD_SYMBOL_inner_join +#define IOD_SYMBOL_inner_join + iod_define_symbol(inner_join) #endif -#ifndef IOD_SYMBOL__else_ -#define IOD_SYMBOL__else_ - iod_define_symbol(else_, _else_) + +#ifndef IOD_SYMBOL_json_key +#define IOD_SYMBOL_json_key + iod_define_symbol(json_key) #endif -#ifndef IOD_SYMBOL__elt -#define IOD_SYMBOL__elt - iod_define_symbol(elt, _elt) + +#ifndef IOD_SYMBOL_json_skip +#define IOD_SYMBOL_json_skip + iod_define_symbol(json_skip) #endif -#ifndef IOD_SYMBOL__cpt -#define IOD_SYMBOL__cpt - iod_define_symbol(cpt, _cpt) + +#ifndef IOD_SYMBOL_len +#define IOD_SYMBOL_len + iod_define_symbol(len) #endif -#ifndef IOD_SYMBOL__as -#define IOD_SYMBOL__as - iod_define_symbol(as, _as) + +#ifndef IOD_SYMBOL_nth_attribute +#define IOD_SYMBOL_nth_attribute + iod_define_symbol(nth_attribute) #endif -#ifndef IOD_SYMBOL__criteria -#define IOD_SYMBOL__criteria - iod_define_symbol(criteria, _criteria) + +#ifndef IOD_SYMBOL_nth_attribute_ +#define IOD_SYMBOL_nth_attribute_ + iod_define_symbol(nth_attribute_) +#endif + +#ifndef IOD_SYMBOL_on +#define IOD_SYMBOL_on + iod_define_symbol(on) +#endif + +#ifndef IOD_SYMBOL_optional +#define IOD_SYMBOL_optional + iod_define_symbol(optional) +#endif + +#ifndef IOD_SYMBOL_order +#define IOD_SYMBOL_order + iod_define_symbol(order) +#endif + +#ifndef IOD_SYMBOL_order_by +#define IOD_SYMBOL_order_by + iod_define_symbol(order_by) +#endif + +#ifndef IOD_SYMBOL_r +#define IOD_SYMBOL_r + iod_define_symbol(r) +#endif + +#ifndef IOD_SYMBOL_select +#define IOD_SYMBOL_select + iod_define_symbol(select) +#endif + +#ifndef IOD_SYMBOL_size +#define IOD_SYMBOL_size + iod_define_symbol(size) #endif -#ifndef IOD_SYMBOL__sum -#define IOD_SYMBOL__sum - iod_define_symbol(sum, _sum) + +#ifndef IOD_SYMBOL_str +#define IOD_SYMBOL_str + iod_define_symbol(str) #endif -#ifndef IOD_SYMBOL__avg -#define IOD_SYMBOL__avg - iod_define_symbol(avg, _avg) + +#ifndef IOD_SYMBOL_stream +#define IOD_SYMBOL_stream + iod_define_symbol(stream) #endif -#ifndef IOD_SYMBOL__stddev -#define IOD_SYMBOL__stddev - iod_define_symbol(stddev, _stddev) + +#ifndef IOD_SYMBOL_sum +#define IOD_SYMBOL_sum + iod_define_symbol(sum) #endif -#ifndef IOD_SYMBOL__optional -#define IOD_SYMBOL__optional - iod_define_symbol(optional, _optional) +#ifndef IOD_SYMBOL_t +#define IOD_SYMBOL_t + iod_define_symbol(t) #endif -#ifndef IOD_SYMBOL__json_key -#define IOD_SYMBOL__json_key - iod_define_symbol(json_key, _json_key) +#ifndef IOD_SYMBOL_table +#define IOD_SYMBOL_table + iod_define_symbol(table) #endif -#ifndef IOD_SYMBOL__json_skip -#define IOD_SYMBOL__json_skip - iod_define_symbol(json_skip, _json_skip) + +#ifndef IOD_SYMBOL_where +#define IOD_SYMBOL_where + iod_define_symbol(where) #endif + diff --git a/tests/readme.cc b/tests/readme.cc index 51ef012..43a3c25 100644 --- a/tests/readme.cc +++ b/tests/readme.cc @@ -1,9 +1,9 @@ #include #include -iod_define_symbol(a, _a); // Refer to members and methods a with symbol _a -iod_define_symbol(b, _b); // Refer to members and methods b with symbol _b -iod_define_symbol(c, _c); // Refer to members and methods b with symbol _c +iod_define_symbol(a); // Refer to members and methods a with symbol _a +iod_define_symbol(b); // Refer to members and methods b with symbol _b +iod_define_symbol(c); // Refer to members and methods b with symbol _c int main() { diff --git a/tests/symbols.hh b/tests/symbols.hh index 5eef45f..24905f6 100644 --- a/tests/symbols.hh +++ b/tests/symbols.hh @@ -1,40 +1,97 @@ -#ifndef IOD_SYMBOL__name -#define IOD_SYMBOL__name - iod_define_symbol(name, _name) +// Generated by iod_generate_symbols. +#include +#ifndef IOD_SYMBOL_a +#define IOD_SYMBOL_a + iod_define_symbol(a) #endif -#ifndef IOD_SYMBOL__city -#define IOD_SYMBOL__city - iod_define_symbol(city, _city) + +#ifndef IOD_SYMBOL_age +#define IOD_SYMBOL_age + iod_define_symbol(age) #endif -#ifndef IOD_SYMBOL__children -#define IOD_SYMBOL__children - iod_define_symbol(children, _children) + +#ifndef IOD_SYMBOL_age2 +#define IOD_SYMBOL_age2 + iod_define_symbol(age2) #endif -#ifndef IOD_SYMBOL__age -#define IOD_SYMBOL__age - iod_define_symbol(age, _age) + +#ifndef IOD_SYMBOL_as +#define IOD_SYMBOL_as + iod_define_symbol(as) #endif -#ifndef IOD_SYMBOL__age2 -#define IOD_SYMBOL__age2 - iod_define_symbol(age2, _age2) + +#ifndef IOD_SYMBOL_avg +#define IOD_SYMBOL_avg + iod_define_symbol(avg) #endif -#ifndef IOD_SYMBOL__person -#define IOD_SYMBOL__person - iod_define_symbol(person, _person) + +#ifndef IOD_SYMBOL_b +#define IOD_SYMBOL_b + iod_define_symbol(b) #endif -#ifndef IOD_SYMBOL__city -#define IOD_SYMBOL__city - iod_define_symbol(city, _city) + +#ifndef IOD_SYMBOL_c +#define IOD_SYMBOL_c + iod_define_symbol(c) #endif -#ifndef IOD_SYMBOL__cp -#define IOD_SYMBOL__cp - iod_define_symbol(cp, _cp) + +#ifndef IOD_SYMBOL_children +#define IOD_SYMBOL_children + iod_define_symbol(children) #endif -#ifndef IOD_SYMBOL__my_json_name -#define IOD_SYMBOL__my_json_name - iod_define_symbol(my_json_name, _my_json_name) + +#ifndef IOD_SYMBOL_city +#define IOD_SYMBOL_city + iod_define_symbol(city) #endif -#ifndef IOD_SYMBOL__username -#define IOD_SYMBOL__username - iod_define_symbol(username, _username) + +#ifndef IOD_SYMBOL_cp +#define IOD_SYMBOL_cp + iod_define_symbol(cp) #endif + +#ifndef IOD_SYMBOL_json_key +#define IOD_SYMBOL_json_key + iod_define_symbol(json_key) +#endif + +#ifndef IOD_SYMBOL_json_skip +#define IOD_SYMBOL_json_skip + iod_define_symbol(json_skip) +#endif + +#ifndef IOD_SYMBOL_my_json_name +#define IOD_SYMBOL_my_json_name + iod_define_symbol(my_json_name) +#endif + +#ifndef IOD_SYMBOL_name +#define IOD_SYMBOL_name + iod_define_symbol(name) +#endif + +#ifndef IOD_SYMBOL_on +#define IOD_SYMBOL_on + iod_define_symbol(on) +#endif + +#ifndef IOD_SYMBOL_optional +#define IOD_SYMBOL_optional + iod_define_symbol(optional) +#endif + +#ifndef IOD_SYMBOL_person +#define IOD_SYMBOL_person + iod_define_symbol(person) +#endif + +#ifndef IOD_SYMBOL_sum +#define IOD_SYMBOL_sum + iod_define_symbol(sum) +#endif + +#ifndef IOD_SYMBOL_username +#define IOD_SYMBOL_username + iod_define_symbol(username) +#endif + diff --git a/tests/symbols.sb b/tests/symbols.sb deleted file mode 100644 index 4b8c676..0000000 --- a/tests/symbols.sb +++ /dev/null @@ -1,10 +0,0 @@ -name -city -children -age -age2 -person -city -cp -my_json_name -username diff --git a/tools/iod_generate_symbols.cc b/tools/iod_generate_symbols.cc index e4682cf..8e41972 100644 --- a/tools/iod_generate_symbols.cc +++ b/tools/iod_generate_symbols.cc @@ -22,7 +22,8 @@ int main(int argc, char* argv[]) set symbols; boost::regex symbol_regex(".?_([[:alnum:]_]+)"); - + std::set keywords = {"alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class", "compl", "const", "constexpr", "const_cast", "continue", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "return", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"}; + auto parse_file = [&] (std::string filename) { ifstream f(filename); @@ -63,7 +64,9 @@ int main(int argc, char* argv[]) std::string s = what[1]; bool is_type = s.size() >= 2 and s[s.size() - 2] == '_' and s[s.size() - 1] == 't'; - if (!std::isalnum(m[0]) and !is_in_string(what.position()) and !is_type) + + if (!std::isalnum(m[0]) and !is_in_string(what.position()) and + !is_type and keywords.find(s) == keywords.end()) symbols.insert(what[1]); start = what[0].second; } From 44e233426ea8d8e20648c30a401a63f202d061b3 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Sun, 15 Feb 2015 13:03:08 +0100 Subject: [PATCH 05/94] Update readme --- README.md | 12 ++++++------ tools/CMakeLists.txt | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b6d9ddf..c71b5e6 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ but powerful operator that is now possible with IOD symbols: #include #include -iod_define_symbol(a, _a); // Refer to members and methods a with symbol _a -iod_define_symbol(b, _b); // Refer to members and methods b with symbol _b -iod_define_symbol(c, _c); // Refer to members and methods c with symbol _c +iod_define_symbol(a); // Refer to members and methods a with symbol _a +iod_define_symbol(b); // Refer to members and methods b with symbol _b +iod_define_symbol(c); // Refer to members and methods c with symbol _c int main() { @@ -50,9 +50,9 @@ to avoid multiple definition, guards should be used such as in the following: ```c++ -#ifndef IOD_SYMBOL__Mysymbol -#define IOD_SYMBOL__Mysymbol - iod_define_symbol(mysymbol, _mysymbol); +#ifndef IOD_SYMBOL_mysymbol +#define IOD_SYMBOL_mysymbol + iod_define_symbol(mysymbol); #endif } ``` diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index dc68240..f30d18f 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -13,3 +13,7 @@ target_link_libraries(iod_generate_symbols boost_regex) install(TARGETS iodc EXPORT IodTargets DESTINATION bin) + +install(TARGETS iod_generate_symbols + EXPORT IodTargets + DESTINATION bin) From ba0868193814e16bc4279dc865e4c2b1645e9935 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Feb 2015 23:27:34 +0100 Subject: [PATCH 06/94] Remove the iod compiler and the dependence to boost regex. --- CMakeLists.txt | 1 - IodUse.cmake | 41 --------- tools/CMakeLists.txt | 8 -- tools/iod_compiler.cc | 159 ---------------------------------- tools/iod_generate_symbols.cc | 15 ++-- 5 files changed, 8 insertions(+), 216 deletions(-) delete mode 100644 IodUse.cmake delete mode 100644 tools/iod_compiler.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index f333832..f3b9bb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,6 @@ configure_file(IodConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" @ONLY) install(FILES - "${PROJECT_SOURCE_DIR}/IodUse.cmake" "${PROJECT_BINARY_DIR}/IodConfig.cmake" "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" DESTINATION share/iod) diff --git a/IodUse.cmake b/IodUse.cmake deleted file mode 100644 index f924304..0000000 --- a/IodUse.cmake +++ /dev/null @@ -1,41 +0,0 @@ -set(IOD_TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/iod_tmp_dir") -file(MAKE_DIRECTORY ${IOD_TMP_DIR}) -set(SYMBOL_INCLUDE_FILE ${IOD_TMP_DIR}/symbol_include.hh) -file(WRITE ${SYMBOL_INCLUDE_FILE} "#include \n") - -set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++14") - -function(add_iod_executable arg1) - - set(sources "") - foreach(iod_compile_rules ${ARGN}) - set(input_file ${CMAKE_CURRENT_SOURCE_DIR}/${iod_compile_rules}) - set(inputp_file ${IOD_TMP_DIR}/${iod_compile_rules}.i) - set(output_file ${IOD_TMP_DIR}/${iod_compile_rules}) - set(sources ${sources} ${output_file}) - - get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) - set(INCLUDE_FLAGS) - foreach(dir ${dirs}) - set(INCLUDE_FLAGS ${INCLUDE_FLAGS} -I ${dir} ) - endforeach() - - add_custom_command(OUTPUT ${inputp_file} - COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_DEFINES} ${CMAKE_CXX_FLAGS} ${INCLUDE_FLAGS} -E ${input_file} > ${inputp_file} - IMPLICIT_DEPENDS CXX ${input_file}) - - add_custom_command(OUTPUT ${output_file} - COMMAND iodc ${inputp_file} ${output_file} - DEPENDS ${inputp_file}) - -# add_custom_command(OUTPUT ${output_file} -# COMMAND iodc ${input_file}.i ${output_file} -# #DEPENDS ${input_file}.i -# IMPLICIT_DEPENDS ${input_file}.i -# ) - - endforeach(iod_compile_rules) - #add_executable(${arg1}_just_for_preprocessor_rules ${ARGN}) - add_executable(${arg1} ${sources}) - -endfunction(add_iod_executable) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index f30d18f..b598151 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,19 +1,11 @@ cmake_minimum_required(VERSION 2.8) project(Iod) -find_package(Boost) add_definitions(-std=c++14) -add_executable(iodc iod_compiler.cc) -target_link_libraries(iodc boost_regex) - add_executable(iod_generate_symbols iod_generate_symbols.cc) target_link_libraries(iod_generate_symbols boost_regex) -install(TARGETS iodc - EXPORT IodTargets - DESTINATION bin) - install(TARGETS iod_generate_symbols EXPORT IodTargets DESTINATION bin) diff --git a/tools/iod_compiler.cc b/tools/iod_compiler.cc deleted file mode 100644 index 87c234d..0000000 --- a/tools/iod_compiler.cc +++ /dev/null @@ -1,159 +0,0 @@ -#include -#include -#include -#include - -std::string symbol_definition(std::string s, std::string name); - -// Iod to C++14 compiler. -// -// Simple but useful syntaxic sugar on top of C++14. -// -// Access to a symbol: @symbol translated to s::_Symbol -// Access to a member via a symbol: o@symbol translated to s::_Symbol.member_access(o); -// Call to a method via a symbol: o@symbol(42) translated to s::_Symbol.method_call(o, 42); -// -// All the symbols used in a C++ file are declared at the beginning of the generated file. -// -int main(int argc, char* argv[]) -{ - using namespace std; - - if (argc != 3) - { - cout << "Usage: " << argv[0] << " input_iod_cpp_file output_cpp_file" << endl; - return 1; - } - - ifstream f(argv[1]); - if (!f) - { - std::cerr << "Cannot open file " << argv[1] << " for reading." << std::endl; - return 1; - } - - set symbols; - set symbols_already_defined; - - // prefix identifier @ symbol_identifier ( - boost::regex symbol_regex("([[:alnum:]_]*)([[:blank:]]*)@[[:blank:]]*([[:alnum:]_]+)[[:blank:]]*(([(][[:blank:]]*[)]?)?)"); - // Matches: - // 1: variable name - // 2: spaces - // 3: symbol - // 4: parenthesis - - vector lines; - - auto to_safe_alias = [] (string s) { - return string("_") + s; - }; - - std::string line; - bool in_raw_string = false; - while (!f.eof()) - { - getline(f, line); - - std::vector dbl_quotes_pos; - bool escaped = false; - for (int i = 0; i < line.size(); i++) - { - if (line[i] == '"' and !escaped) dbl_quotes_pos.push_back(i); - else if (line[i] == '\\') escaped = !escaped; - else escaped = false; - } - - auto is_in_string = [&] (int p) { - int i = 0; - while (i < dbl_quotes_pos.size() and dbl_quotes_pos[i] <= p) i++; - return i % 2; - }; - - auto fmt = [&] (const boost::smatch& s) -> std::string { - if (is_in_string(s.position())) return s[0]; - else - { - std::string symbol, variable_name, parenthesis; - variable_name = s[1]; - string spaces = s[2]; - symbol = s[3]; - parenthesis = s[4]; - symbols.insert(symbol); - ostringstream ss; - - if (variable_name.length() > 0) - { - ss << "s::" << to_safe_alias(symbol); - if (parenthesis.length()) - { - ss << ".method_call(" << variable_name; - if (parenthesis.back() == ')') ss << ")"; - else ss << ", "; - } - else - ss << ".member_access(" << variable_name << ")"; - } - else ss << spaces << "s::" << to_safe_alias(symbol) << parenthesis; - - return ss.str(); - } - }; - - line = boost::regex_replace(line, symbol_regex, fmt); - lines.push_back(line); - - - // Check for symbols already defined. - { - boost::regex sab(".*namespace s { struct ([A-Za-z0-9_]+)_t.*"); - boost::smatch what; - if (boost::regex_match(line, what, sab)) - { - symbols_already_defined.insert(what[1]); - } - } - - } - - std::ofstream os(argv[2]); - if (!os) - { - std::cerr << "Cannot open file " << argv[2] << " for writting." << std::endl; - return 2; - } - - os << "// Generated by the iod compiler." << endl; - std::stringstream symbols_content; - //os << "#include " << endl; - for (string s : symbols) - { - std::string safe_alias = to_safe_alias(s); - if (symbols_already_defined.find(safe_alias) == symbols_already_defined.end()) - symbols_content << symbol_definition(s, safe_alias) << endl; - } - - int i = 1; - for (auto line : lines) - { - if (line == "int __compiler_insert_symbols_here__();") - os << symbols_content.str() << endl; - else - os << line << endl; - i++; - } -} - -std::string symbol_definition(std::string s, std::string name) -{ - std::string body = R"definition( -namespace s { struct __N___t : iod::symbol<__N___t> { constexpr __N___t() {} typedef iod::symbol<__N___t> super; using super::operator=; inline const char* name() const { return "__S__"; } template inline const auto& member_access(const T& o) const { return o.__S__; } template inline auto& member_access(T& o) const { return o.__S__; } template inline auto method_call(const T& o, A... args) const { return o.__S__(args...); } template > struct variable_type : public iod::variable> { typedef T value_type; typedef INFO attributes_type; typedef __N___t symbol_type; variable_type() {} template variable_type(V v) : __S__(v) {} inline value_type& value() { return __S__; } inline const value_type& value() const { return __S__; } auto symbol() const { return __N___t(); } auto symbol_name() const { return "__S__"; } auto attributes() const { return INFO(); } value_type __S__; }; }; constexpr __N___t __N__; } -)definition"; - - boost::regex s_regex("__S__"); - boost::regex n_regex("__N__"); - body = boost::regex_replace(body, s_regex, s); - body = boost::regex_replace(body, n_regex, name); - - return body; -} diff --git a/tools/iod_generate_symbols.cc b/tools/iod_generate_symbols.cc index 8e41972..414561d 100644 --- a/tools/iod_generate_symbols.cc +++ b/tools/iod_generate_symbols.cc @@ -1,7 +1,8 @@ +#include #include #include #include -#include +#include std::string symbol_definition(std::string s); @@ -20,8 +21,8 @@ int main(int argc, char* argv[]) return 1; } - set symbols; - boost::regex symbol_regex(".?_([[:alnum:]_]+)"); + std::set symbols; + std::regex symbol_regex(".?_([[:alnum:]_]+)"); std::set keywords = {"alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class", "compl", "const", "constexpr", "const_cast", "continue", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "return", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"}; auto parse_file = [&] (std::string filename) { @@ -56,8 +57,8 @@ int main(int argc, char* argv[]) std::string::const_iterator start, end; start = line.begin(); end = line.end(); - boost::match_results what; - boost::match_flag_type flags = boost::match_default; + std::match_results what; + std::regex_constants::match_flag_type flags = std::regex_constants::match_default; while(regex_search(start, end, what, symbol_regex, flags)) { std::string m = what[0]; @@ -114,7 +115,7 @@ std::string symbol_definition(std::string s) #endif )cpp"; - boost::regex s_regex("__S__"); - body = boost::regex_replace(body, s_regex, s); + std::regex s_regex("__S__"); + body = std::regex_replace(body, s_regex, s); return body; } From 01d1917ab19be0408335167315fe96e46512277f Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Feb 2015 23:27:54 +0100 Subject: [PATCH 07/94] Serialize json arrays. --- iod/json.hh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/iod/json.hh b/iod/json.hh index 1679999..822fe71 100644 --- a/iod/json.hh +++ b/iod/json.hh @@ -33,6 +33,10 @@ namespace iod template inline std::string json_encode(const sio& o); + // Encode \o into a json string. + template + inline std::string json_encode(const std::vector& v); + // Encode \o into a stream. template inline void json_encode(const sio& o, S& stream); @@ -565,6 +569,14 @@ namespace iod json_internals::json_encode_(o, stream); } + template + inline std::string json_encode(const std::vector& v) + { + std::stringstream ss; + json_internals::json_encode_(v, ss); + return ss.str(); + } + } #endif From 0de037b8621ce10caeaea898600e5c002a597517 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Feb 2015 23:28:56 +0100 Subject: [PATCH 08/94] Remove the old example --- example.cc | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 example.cc diff --git a/example.cc b/example.cc deleted file mode 100644 index 10c5ad2..0000000 --- a/example.cc +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -#include -#include "iod_json.hh" - -// Declaration of the attributes used by the inline object definitions. -iod_define_attribute(name) -iod_define_attribute(age) -iod_define_attribute(cars) -iod_define_attribute(model) -iod_define_attribute(cities) -iod_define_attribute(lastname) -iod_define_attribute(inc_age) - -int main() -{ - - // Inline object definition. - auto person = iod( - *name = ("Philippe"), // stared fields are serialized. - *age = 42, - - inc_age = [] (auto& self, int inc) { self.age += inc; }, // Requires C++14. - - *cities = {"Paris", "Toronto", "New York City"}, - *cars = { - iod(*name = ("Renault"), model = std::string("Clio")), - // All elements of an array must have the same type. - iod(*name = ("Mercedes"), model = std::string("Class A")) - } - ); - - // Access to the content of the object. - std::cout << person.name << std::endl; - std::cout << person.cars[1].model << std::endl; - - person(inc_age, 10); // Call the inc_age method with arguments (person, 10). - - // Serialize an object to json. - std::string json = iod_to_json(person); - std::cout << json << std::endl; - - // Load an object from a json string. - std::string json_string = R"json({"name":"John", "age": 12})json"; - auto test = iod(*name = "", *age = int()); - - iod_from_json(test, json_string); - - // Extend and object. (todo) - // auto extended_person = iod_extend(person, iod(lastname_ = "Doe")); -} From 281f788e068c293304fd41b968d5a137fe9f4612 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Mon, 2 Mar 2015 01:15:07 +0100 Subject: [PATCH 09/94] Properly forward references in di. --- iod/bind_method.hh | 6 ++++++ iod/di.hh | 14 ++++++++------ tests/di.cc | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/iod/bind_method.hh b/iod/bind_method.hh index d4c5fd5..c86d57b 100644 --- a/iod/bind_method.hh +++ b/iod/bind_method.hh @@ -8,5 +8,11 @@ namespace iod { return [&o, m] (ARGS... a) { return (o.*m)(std::forward(a)...); }; } + + template + auto bind_method(O& o, R (O::*m)(ARGS...) const) + { + return [&o, m] (ARGS... a) { return (o.*m)(std::forward(a)...); }; + } } diff --git a/iod/di.hh b/iod/di.hh index 691a6b2..8005242 100644 --- a/iod/di.hh +++ b/iod/di.hh @@ -5,6 +5,7 @@ #include #include #include +#include namespace iod { @@ -60,13 +61,13 @@ namespace iod using tuple_filter_references_t = typename tuple_filter_references::type; template - auto call_factory_instantiate(M& factory, C&& ctx, std::tuple*) + decltype(auto) call_factory_instantiate(M& factory, C&& ctx, std::tuple*) { return factory.instantiate(tuple_get_by_type(ctx)...); } template - auto call_factory_instantiate_static(C&& ctx, std::tuple*) + decltype(auto) call_factory_instantiate_static(C&& ctx, std::tuple*) { return std::decay_t::instantiate(tuple_get_by_type(ctx)...); } @@ -215,17 +216,17 @@ namespace iod typedef find_di_factory_t FT; return iod::static_if::value>( // If to_inject embed a factory, call it. - [&] (auto&& deps, auto* e, auto* ft_) -> auto { + [&] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { typedef std::remove_pointer_t FT_; typedef iod::callable_arguments_tuple_t ARGS; - auto instantiate = [&] (auto&& ctx) + auto instantiate = [&] (auto&& ctx) -> decltype(auto) { return call_factory_instantiate(tuple_get_by_type(deps), ctx, (ARGS*)0); }; return f(instantiate, (ARGS*)0); }, // If the argument type provide a static instantiate method, call it. - [&] (auto&& deps, auto* e, auto* ft_) -> auto { + [&] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { typedef std::remove_pointer_t> E2; static_assert(has_instantiate_static_method::value, "Dependency injection failed. Cannot resolve."); @@ -339,7 +340,8 @@ namespace iod typedef tuple_remove_rvalues_t ctx_type2; typedef tuple_filter_references_t ctx_type3; - return create_stack_and_call((ctx_type3*)0, (std::tuple*)0, fun, to_inject...); + //void* x = *(ctx_type3*)0; + return create_stack_and_call((ctx_type2*)0, (std::tuple*)0, fun, to_inject...); } } diff --git a/tests/di.cc b/tests/di.cc index 52d040b..6d17429 100644 --- a/tests/di.cc +++ b/tests/di.cc @@ -1,4 +1,5 @@ #include +#include #include @@ -28,6 +29,15 @@ struct B { } }; + +int mref_int = 42; + +struct Mref { + int& instantiate() { + return mref_int; + } +}; + struct D_factory; struct D { @@ -200,4 +210,13 @@ int main() iod::di_call(fun9, with_data{"toto"}); iod::di_call(fun10, with_data{"toto"}); + + y = 10; + auto f2 = [] (int& x) { x+= 20; }; + iod::di_call(f2, y); + assert(y == 30); + + // test reference. + auto f3 = [] (int& x) { assert(&x == &mref_int); }; + iod::di_call(f3, Mref()); } From e5d0eeb787a3d6ed0d63a9c3d7571e1cdcd8b8d3 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Wed, 4 Mar 2015 08:46:23 +0100 Subject: [PATCH 10/94] Di: Handle const and forward arguments to instantiate. --- iod/di.hh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/iod/di.hh b/iod/di.hh index 8005242..70f1e34 100644 --- a/iod/di.hh +++ b/iod/di.hh @@ -63,13 +63,13 @@ namespace iod template decltype(auto) call_factory_instantiate(M& factory, C&& ctx, std::tuple*) { - return factory.instantiate(tuple_get_by_type(ctx)...); + return factory.instantiate(std::forward(tuple_get_by_type(ctx))...); } template decltype(auto) call_factory_instantiate_static(C&& ctx, std::tuple*) { - return std::decay_t::instantiate(tuple_get_by_type(ctx)...); + return std::decay_t::instantiate(std::forward(tuple_get_by_type(ctx))...); } // dependencies_of allows to forward dependencies of a function to another. @@ -203,8 +203,10 @@ namespace iod return static_if::value or tuple_embeds::value or - tuple_embeds::value - >( + tuple_embeds::value or + tuple_embeds::value or + tuple_embeds::value or + tuple_embeds::value>( [&] (auto& to_inject) -> decltype(auto) { // If to_inject already embeds an element of type E, return it. auto instantiate = [&] (auto) -> decltype(auto) { From a0eba96f8dd9294d078b1b369ec145d56d6cd545 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Sun, 15 Mar 2015 19:20:49 +0100 Subject: [PATCH 11/94] Remove dependency to boost_regex. --- tools/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index b598151..7ff7dc0 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -4,7 +4,6 @@ project(Iod) add_definitions(-std=c++14) add_executable(iod_generate_symbols iod_generate_symbols.cc) -target_link_libraries(iod_generate_symbols boost_regex) install(TARGETS iod_generate_symbols EXPORT IodTargets From d75bb2dceb0ee74b63c962ea23bb667b3c56d2fc Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Mon, 16 Mar 2015 14:40:50 +0100 Subject: [PATCH 12/94] Fix cmakelists.txt. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f333832..9f68b50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ set(CMAKE_CONFIG_DEST "share/iod") include(CMakePackageConfigHelpers) configure_package_config_file ( - ${CMAKE_SOURCE_DIR}/IodConfig.cmake.in + ${CMAKE_CURRENT_LIST_DIR}/IodConfig.cmake.in ${CMAKE_BINARY_DIR}/IodConfig.cmake INSTALL_DESTINATION ${CMAKE_CONFIG_DEST} PATH_VARS IOD_INCLUDE_DIR CMAKE_CONFIG_DEST) From 03cf0fcb6529f8a35c39e336083f5665c14daf9b Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Mar 2015 16:28:43 +0100 Subject: [PATCH 13/94] Add biicode suport. --- CMakeLists.txt | 17 +++++++++++++++++ IodConfig.cmake.in | 2 -- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 192d51b..066d0f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,16 @@ +IF(BIICODE) + + ADD_BIICODE_TARGETS() + +IF(APPLE) + TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE "-std=c++14 -stdlib=libc++") +ELSEIF (WIN32 OR UNIX) + TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE "-std=c++14") +ENDIF(APPLE) + +ELSE() + + cmake_minimum_required(VERSION 2.8) project(Iod) @@ -31,3 +44,7 @@ install(FILES # Install the export set for use with the install-tree install(EXPORT IodTargets DESTINATION ${CMAKE_CONFIG_DEST}) + + +ENDIF() # BIICODE + diff --git a/IodConfig.cmake.in b/IodConfig.cmake.in index 7752896..aec62e3 100644 --- a/IodConfig.cmake.in +++ b/IodConfig.cmake.in @@ -7,5 +7,3 @@ set_and_check(IOD_INCLUDE_DIR "@PACKAGE_IOD_INCLUDE_DIR@") include("@PACKAGE_CMAKE_CONFIG_DEST@/IodTargets.cmake") - -set_and_check(IOD_USE_FILE "@PACKAGE_CMAKE_CONFIG_DEST@/IodUse.cmake") From 47970f9e2f90accf6580c12c6c9f766f069e4c0f Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Mar 2015 16:30:02 +0100 Subject: [PATCH 14/94] Add tests subdirectory in cmakelists. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 066d0f5..6bdf059 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ install(DIRECTORY iod DESTINATION include FILES_MATCHING PATTERN "*.hpp") add_subdirectory(tools) +add_subdirectory(tests) set(IOD_INCLUDE_DIR "include") set(CMAKE_CONFIG_DEST "share/iod") From 2128ed1305dadf3ac03b84bc6463f5ea83606f93 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Mar 2015 16:32:37 +0100 Subject: [PATCH 15/94] Add biicode.conf. --- biicode.conf | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 biicode.conf diff --git a/biicode.conf b/biicode.conf new file mode 100644 index 0000000..16829c1 --- /dev/null +++ b/biicode.conf @@ -0,0 +1,54 @@ +# Biicode configuration file + +[requirements] + + +[parent] + matt42/iod: 0 +[paths] + # Local directories to look for headers (within block) + / + # include + +[dependencies] + # Manual adjust file implicit dependencies, add (+), remove (-), or overwrite (=) + # hello.h + hello_imp.cpp hello_imp2.cpp + # *.h + *.cpp + +[mains] + # Manual adjust of files that define an executable + # !main.cpp # Do not build executable from this file + # main2.cpp # Build it (it doesnt have a main() function, but maybe it includes it) + #!tests/*cc + !tests/linq.cc + !tests/iod_query_stl.cc + !tests/iod_query_sql.cc + +[tests] + # Manual adjust of files that define a CTest test + # test/* pattern to evaluate this test/ folder sources like tests + tests/json.cc + tests/core.cc + tests/callable_traits.cc + tests/apply.cc + tests/foreach.cc + tests/readme.cc + tests/di.cc + tests/bind_method.cc + tests/tuple.cc + +[hooks] + # These are defined equal to [dependencies],files names matching bii*stage*hook.py + # will be launched as python scripts at stage = {post_process, clean} + # CMakeLists.txt + bii/my_post_process1_hook.py bii_clean_hook.py + +[includes] + # Mapping of include patterns to external blocks + # hello*.h: user3/depblock # includes will be processed as user3/depblock/hello*.h + +[data] + # Manually define data files dependencies, that will be copied to bin for execution + # By default they are copied to bin/user/block/... which should be taken into account + # when loading from disk such data + # image.cpp + image.jpg # code should write open("user/block/image.jpg") + From 64f54669d5a9432a1f0addb3261e9272d36abf67 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Mar 2015 16:41:03 +0100 Subject: [PATCH 16/94] Add bii directory. --- bii/.hive.db | Bin 0 -> 240640 bytes bii/layout.bii | 12 ++++++++++++ bii/policies.bii | 49 +++++++++++++++++++++++++++++++++++++++++++++++ bii/settings.bii | 2 ++ 4 files changed, 63 insertions(+) create mode 100644 bii/.hive.db create mode 100644 bii/layout.bii create mode 100644 bii/policies.bii create mode 100644 bii/settings.bii diff --git a/bii/.hive.db b/bii/.hive.db new file mode 100644 index 0000000000000000000000000000000000000000..73a984d9bcd936a875e20ae56eb2ccfb9a8ee439 GIT binary patch literal 240640 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 + priority: 1 + +# For all other users only accept STABLE blocks +- block: ALL + version: tag==STABLE + priority: 1 + +# Examples: +# Let's say that you (maya) introduce a dependency to some cell in willy/block and +# you want to reuse as a Beta tester of such block, you should write a new rule: +#- block: block == "willy/block" +# version: tag>=BETA +# priority: 1 +# +# If you want to accept all ALPHA VERSIONS of another user's published +# blocks with priority 1. +#- block: block.user == "ANOTHER_USER" +# version: tag==ALPHA +# priority: 1 + + + diff --git a/bii/settings.bii b/bii/settings.bii new file mode 100644 index 0000000..9989d31 --- /dev/null +++ b/bii/settings.bii @@ -0,0 +1,2 @@ +cmake: {generator: Unix Makefiles} +os: {arch: 64bit, family: Linux} From 8c6216b1f86a2a13cc857881cefb02a46832aaa1 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Mar 2015 18:06:35 +0100 Subject: [PATCH 17/94] Update biicode.conf. --- biicode.conf | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/biicode.conf b/biicode.conf index 16829c1..c52b801 100644 --- a/biicode.conf +++ b/biicode.conf @@ -16,26 +16,9 @@ # *.h + *.cpp [mains] - # Manual adjust of files that define an executable - # !main.cpp # Do not build executable from this file - # main2.cpp # Build it (it doesnt have a main() function, but maybe it includes it) - #!tests/*cc - !tests/linq.cc - !tests/iod_query_stl.cc - !tests/iod_query_sql.cc + !* # Nothing to compile [tests] - # Manual adjust of files that define a CTest test - # test/* pattern to evaluate this test/ folder sources like tests - tests/json.cc - tests/core.cc - tests/callable_traits.cc - tests/apply.cc - tests/foreach.cc - tests/readme.cc - tests/di.cc - tests/bind_method.cc - tests/tuple.cc [hooks] # These are defined equal to [dependencies],files names matching bii*stage*hook.py From 7c8012fcb37e7b89232078f172eda51bb03b7bd3 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Mar 2015 20:52:26 +0100 Subject: [PATCH 18/94] Deactivate cmake package generation. (travis does not support CMakePackageConfigHelpers) --- CMakeLists.txt | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f3b9bb8..e817824 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 2.8) project(Iod) +find_package(Boost REQUIRED) # For lexical_cast install(DIRECTORY iod DESTINATION include FILES_MATCHING PATTERN "*.hh") @@ -9,25 +10,25 @@ install(DIRECTORY iod DESTINATION include add_subdirectory(tools) -set(IOD_INCLUDE_DIR "include") -set(CMAKE_CONFIG_DEST "share/iod") +#set(IOD_INCLUDE_DIR "include") +#set(CMAKE_CONFIG_DEST "share/iod") -include(CMakePackageConfigHelpers) -configure_package_config_file ( - ${CMAKE_SOURCE_DIR}/IodConfig.cmake.in - ${CMAKE_BINARY_DIR}/IodConfig.cmake - INSTALL_DESTINATION ${CMAKE_CONFIG_DEST} - PATH_VARS IOD_INCLUDE_DIR CMAKE_CONFIG_DEST) +#include(CMakePackageConfigHelpers) +#configure_package_config_file ( +# ${CMAKE_SOURCE_DIR}/IodConfig.cmake.in +# ${CMAKE_BINARY_DIR}/IodConfig.cmake +# INSTALL_DESTINATION ${CMAKE_CONFIG_DEST} +# PATH_VARS IOD_INCLUDE_DIR CMAKE_CONFIG_DEST) -export(PACKAGE Iod) +#export(PACKAGE Iod) -configure_file(IodConfigVersion.cmake.in - "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" @ONLY) +#configure_file(IodConfigVersion.cmake.in +# "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" @ONLY) -install(FILES - "${PROJECT_BINARY_DIR}/IodConfig.cmake" - "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" - DESTINATION share/iod) +#install(FILES +# "${PROJECT_BINARY_DIR}/IodConfig.cmake" +# "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" +# DESTINATION share/iod) # Install the export set for use with the install-tree -install(EXPORT IodTargets DESTINATION ${CMAKE_CONFIG_DEST}) +#install(EXPORT IodTargets DESTINATION ${CMAKE_CONFIG_DEST}) From 5f9bc410bdecc424cc430890431a93e28a2f98cc Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Mar 2015 22:13:01 +0100 Subject: [PATCH 19/94] Fix stringview headers. --- iod/stringview.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iod/stringview.hh b/iod/stringview.hh index 77849fb..0a8fa4b 100644 --- a/iod/stringview.hh +++ b/iod/stringview.hh @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace iod { From d24878ae38ca1f1d8024f1171655162025ff4d56 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 17 Mar 2015 22:13:19 +0100 Subject: [PATCH 20/94] Fix stringview headers. --- iod/stringview.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/iod/stringview.hh b/iod/stringview.hh index 0a8fa4b..158ef25 100644 --- a/iod/stringview.hh +++ b/iod/stringview.hh @@ -1,6 +1,7 @@ #pragma once #include +#include namespace iod { From 3c382fef7e06ec0a65dbb95f2409b06f34dafb2f Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Fri, 3 Apr 2015 00:53:31 +0200 Subject: [PATCH 21/94] Fix readme. --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c71b5e6..10f9391 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,7 @@ iod_define_symbol(c); // Refer to members and methods c with symbol _c int main() { // Symbols are located in namespace s to avoid name clash. - using s::_a; - using s::_b; - using s::_c; + using s; auto print_member = [] (auto& obj, auto& m) { @@ -45,7 +43,7 @@ Without symbols (or other similar constructs), it is not possible to write such a generic print_member function. Without, one would have to write the three version accessing the three different members. -By convention all the symbols starts with _[uppercase character]. And +By convention all the symbols starts with _[lowercase character]. And to avoid multiple definition, guards should be used such as in the following: From c1580a5a017e357cd1d947118c22de2c650a2873 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Mon, 13 Apr 2015 19:07:56 +0200 Subject: [PATCH 22/94] Add sstream header. --- tools/iod_generate_symbols.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/iod_generate_symbols.cc b/tools/iod_generate_symbols.cc index 414561d..224d943 100644 --- a/tools/iod_generate_symbols.cc +++ b/tools/iod_generate_symbols.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include #include From da7edaee13717547c460b830bb9497a5b3bfb425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20B=C3=B6hn=20/=20FI=24H2k?= Date: Fri, 5 Jun 2015 09:12:39 -0400 Subject: [PATCH 23/94] Explicit #include for std::string --- iod/grammar.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/iod/grammar.hh b/iod/grammar.hh index 808be31..928b855 100644 --- a/iod/grammar.hh +++ b/iod/grammar.hh @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include From 6b0cdf300d3f3c38e74d7a5dcb16d1a8f9f07f93 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Mon, 31 Aug 2015 20:06:27 +0200 Subject: [PATCH 24/94] Fix Named function parameters values in Readme.txt --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 10f9391..c8634b0 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ json_decode(u2, R"({"username":"John","city":22})"); In classic C++, you would define a function taking optional arguments as : ```c++ -void fun(int mandatory_arg, int optional_arg1 = 1, int optional_arg2 = 12, int optional_arg3 = 12); +void fun(int mandatory_arg, int optional_arg1 = 1, int optional_arg2 = 12, int optional_arg3 = 32); ``` This has to drawbacks: First, it is not practical if the user need to @@ -171,8 +171,8 @@ void fun(int mandatory_arg, const O&... opts) { const auto options = D(opts...); int optional_arg1 = options.get(_optional_arg1, 1); // return options.optional_arg1 or 1 if not set. - int optional_arg2 = options.get(_optional_arg2, 1); - int optional_arg3 = options.get(_optional_arg3, 1); + int optional_arg2 = options.get(_optional_arg2, 12); + int optional_arg3 = options.get(_optional_arg3, 32); } fun(1, _optional_arg3 = 2); // Set the thirds argument and leave the two others to their default value. From d947c22b7b77960f97a18af75304a14a31c639d6 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 5 Jan 2016 10:03:54 +0100 Subject: [PATCH 25/94] Updates for the next version of silicon. Fix a bug in DI: destructors were called twice insted of once in some cases. --- iod/di.hh | 5 +- iod/foreach.hh | 3 +- iod/grammar.hh | 143 ++++++++++++++++++++++++++++++++++++++----- iod/json.hh | 84 +++++++++++++++++-------- iod/linq_evaluate.hh | 2 +- iod/sio.hh | 142 ++++++++++++++++-------------------------- iod/sio_utils.hh | 39 +++++++++--- iod/symbol.hh | 3 +- tests/core.cc | 4 ++ tests/json.cc | 16 ++++- 10 files changed, 296 insertions(+), 145 deletions(-) diff --git a/iod/di.hh b/iod/di.hh index 70f1e34..a056dfe 100644 --- a/iod/di.hh +++ b/iod/di.hh @@ -206,7 +206,8 @@ namespace iod tuple_embeds::value or tuple_embeds::value or tuple_embeds::value or - tuple_embeds::value>( + tuple_embeds::value + >( [&] (auto& to_inject) -> decltype(auto) { // If to_inject already embeds an element of type E, return it. auto instantiate = [&] (auto) -> decltype(auto) { @@ -340,7 +341,7 @@ namespace iod // Remove the rvalues references to be able to store the context. typedef tuple_remove_rvalues_t ctx_type2; - typedef tuple_filter_references_t ctx_type3; + //typedef tuple_filter_references_t ctx_type3; //void* x = *(ctx_type3*)0; return create_stack_and_call((ctx_type2*)0, (std::tuple*)0, fun, to_inject...); diff --git a/iod/foreach.hh b/iod/foreach.hh index 04cb75c..60732e1 100644 --- a/iod/foreach.hh +++ b/iod/foreach.hh @@ -70,7 +70,7 @@ namespace iod { auto h = [] (auto&& a) -> auto&& // avoid the lambda to convert references to values. { - return std::forward())>(a.template get_nth_attribute()); + return std::forward())>(a.template get_nth_member()); }; typedef decltype(h) H; typedef decltype(proxy_apply(args_tuple, std::declval(), f)) return_type; @@ -90,6 +90,7 @@ namespace iod } + template struct foreach_tuple_caller { diff --git a/iod/grammar.hh b/iod/grammar.hh index 808be31..5d6b106 100644 --- a/iod/grammar.hh +++ b/iod/grammar.hh @@ -50,7 +50,7 @@ namespace iod struct symbol; template - struct member_accessible; + struct array_subscriptable; template struct callable; @@ -58,6 +58,15 @@ namespace iod template struct assignable; + template + struct array_subscriptable; + + // template + // struct dividable; + + // template + // struct multipliable; + template auto foreach_prev(std::tuple& a1, T&&... args); template @@ -223,13 +232,13 @@ namespace iod template struct function_call_exp : - public member_accessible>, + public array_subscriptable>, public callable>, public assignable>, public Exp> { using assignable>::operator=; - using member_accessible>::operator[]; + using array_subscriptable>::operator[]; function_call_exp() {} function_call_exp(const M& m, A&&... a) @@ -269,16 +278,16 @@ namespace iod }; template - struct member_accessor_exp : - public member_accessible>, - public callable>, - public assignable>, - public Exp> + struct array_subscript_exp : + public array_subscriptable>, + public callable>, + public assignable>, + public Exp> { - using assignable>::operator=; + using assignable>::operator=; - member_accessor_exp() {} - member_accessor_exp(const O& o, const M& m) : object(o), member(m) {} + array_subscript_exp() {} + array_subscript_exp(const O& o, const M& m) : object(o), member(m) {} template auto visit(F f) { return std::make_tuple(f(object), f(member)); } @@ -286,7 +295,7 @@ namespace iod auto transform(F f, C ctx) { auto o = exp_transform(object, f, ctx); auto m = exp_transform(member, f, ctx); - return member_accessor_exp(o, m); + return array_subscript_exp(o, m); } template @@ -294,7 +303,7 @@ namespace iod { auto l = exp_transform_iterate(object, f, ctx); auto r = exp_transform_iterate(member, f, l.second); - return std::make_pair(member_accessor_exp + return std::make_pair(array_subscript_exp (l.first, r.first), r.second); } @@ -343,15 +352,90 @@ namespace iod R right; }; + + // template + // struct multiply_exp : + // public dividable>, + // public multipliable>, + // public assignable>, + // public Exp> + // { + // multiply_exp(L&& l, R&& r) : left(l), right(r) {} + // multiply_exp(const L& l, const R& r) : left(l), right(r) {} + + // template + // auto visit(F f) { return std::make_tuple(f(left), f(right)); } + + // template + // auto transform(F f, C ctx) { + // auto l = exp_transform(left, f, ctx); + // auto r = exp_transform(right, f, ctx); + // return multiply_exp(l, r); + // } + + // template + // decltype(auto) transform_iterate(F f, C ctx) + // { + // auto l = exp_transform_iterate(left, f, ctx); + // auto r = exp_transform_iterate(right, f, l.second); + // return std::make_pair(multiply_exp + // (l.first, r.first), r.second); + // } + // auto children_tuple() { return std::make_tuple(left, right); } + // template + // inline decltype(auto) evaluate(M eval, C& ctx) { + // return exp_evaluate(left, eval, ctx) = exp_evaluate(right, eval, ctx); + // } + // L left; + // R right; + // }; + + // template + // struct divide_exp : + // public dividable>, + // public multipliable>, + // public assignable>, + // public Exp> + // { + // divide_exp(L&& l, R&& r) : left(l), right(r) {} + // divide_exp(const L& l, const R& r) : left(l), right(r) {} + + // template + // auto visit(F f) { return std::make_tuple(f(left), f(right)); } + + // template + // auto transform(F f, C ctx) { + // auto l = exp_transform(left, f, ctx); + // auto r = exp_transform(right, f, ctx); + // return divide_exp(l, r); + // } + + // template + // decltype(auto) transform_iterate(F f, C ctx) + // { + // auto l = exp_transform_iterate(left, f, ctx); + // auto r = exp_transform_iterate(right, f, l.second); + // return std::make_pair(divide_exp + // (l.first, r.first), r.second); + // } + // auto children_tuple() { return std::make_tuple(left, right); } + // template + // inline decltype(auto) evaluate(M eval, C& ctx) { + // return exp_evaluate(left, eval, ctx) = exp_evaluate(right, eval, ctx); + // } + // L left; + // R right; + // }; + template - struct member_accessible + struct array_subscriptable { public: // Member accessor template constexpr auto operator[](const S& s) const { - return member_accessor_exp(*static_cast(this), s); + return array_subscript_exp(*static_cast(this), s); } }; @@ -370,6 +454,30 @@ namespace iod }; + // template + // struct multipliable + // { + // public: + // template + // constexpr auto operator*(A a) const + // { + // return multiply_exp>(*static_cast(this), + // std::forward>(a)); + // } + // }; + + // template + // struct dividable + // { + // public: + // template + // constexpr auto operator/(A a) const + // { + // return divide_exp>(*static_cast(this), + // std::forward>(a)); + // } + // }; + template struct assignable { @@ -403,8 +511,11 @@ namespace iod #define iod_query_declare_binary_op(OP, NAME) \ template \ - struct NAME##_exp : public Exp> \ + struct NAME##_exp : \ + public assignable>, \ + public Exp> \ { \ + using assignable>::operator=; \ NAME##_exp() {} \ NAME##_exp(A a, B b) : lhs(a), rhs(b) {} \ typedef A lhs_type; \ diff --git a/iod/json.hh b/iod/json.hh index 822fe71..af9a5e7 100644 --- a/iod/json.hh +++ b/iod/json.hh @@ -377,22 +377,25 @@ namespace iod int pos; }; - inline void iod_attr_from_json(sio<>&, json_parser&) + template + inline void iod_attr_from_json(S*, sio<>&, json_parser&) { } - template - inline void iod_from_json_(T& t, json_parser& p) + template + inline void iod_from_json_(S*, T& t, json_parser& p) { p >> fill(t); } - inline void iod_from_json_(std::string& t, json_parser& p) + template + inline void iod_from_json_(S*, std::string& t, json_parser& p) { p >> '"' >> fill(t) >> '"'; } - inline void iod_from_json_(stringview& t, json_parser& p) + template + inline void iod_from_json_(S*, stringview& t, json_parser& p) { p >> '"' >> fill(t) >> '"'; } @@ -413,17 +416,20 @@ namespace iod } // Parse a json hashmap. - template - inline void iod_attr_from_json(sio& o, json_parser& p) + template + inline void iod_attr_from_json(const sio<>*, O& o, json_parser& p) {} + template + inline void iod_attr_from_json(const sio*, O& o, json_parser& p) { p >> p.spaces; struct attr_info { bool filled; stringview name; }; - attr_info A[std::remove_reference_t::size()]; - + attr_info A[sio::size()]; + + sio scheme;// = *(sio*)(nullptr); int i = 0; - foreach(o) | [&] (auto& m) + foreach(scheme) | [&] (const auto& m) { A[i].filled = false; stringview name(m.symbol().name(), strlen(m.symbol().name())); @@ -443,17 +449,21 @@ namespace iod int i = 0; bool attr_found = false; - foreach(o) | [&] (auto& m) + foreach(scheme) | [&] (auto& m) { if (!m.attributes().has(_json_skip) and !attr_found and attr_name == A[i].name) { - iod_from_json_(m.value(), p); + iod_from_json_(&m.value(), m.symbol().member_access(o), p); A[i].filled = true; attr_found = true; } i++; }; - // Fixme: if !attr_found, skip the json value. + // if !attr_found, throw an error. + if (!attr_found) + throw std::runtime_error(std::string("json_decode error: unexpected key ") + + attr_name.to_std_string()); + p >> p.spaces; if (p.peak() == ',') p.eat_one(); @@ -467,7 +477,7 @@ namespace iod } i = 0; - foreach(o) | [&] (auto& m) { + foreach(scheme) | [&] (auto& m) { if (!m.attributes().has(_json_skip) and !m.attributes().has(_optional) and !A[i].filled) throw std::runtime_error(std::string("json_decode error: missing field ") + m.symbol().name()); @@ -476,8 +486,8 @@ namespace iod } // Parse an array. - template - inline void iod_from_json_(std::vector& array, json_parser& p) + template + inline void iod_from_json_(S*, std::vector& array, json_parser& p) { p >> '[' >> p.spaces; if (p.peak() == ']') @@ -490,7 +500,7 @@ namespace iod while (p.peak() != ']') { T t; - iod_from_json_(t, p); + iod_from_json_((typename S::value_type*)0, t, p); array.push_back(t); p >> p.spaces; if (p.peak() == ']') @@ -502,20 +512,20 @@ namespace iod p >> ']'; } - template - inline void iod_from_json_(sio& o, json_parser& p) + template + inline void iod_from_json_(sio* s, O& o, json_parser& p) { p >> p.spaces >> '{'; - iod_attr_from_json(o, p); + iod_attr_from_json(s, o, p); p >> p.spaces >> '}'; } - template - inline void iod_from_json_(sio& o, const std::string& str) + template + inline void iod_from_json_(const S* s, O& o, const std::string& str) { json_parser p(str); if (str.size() > 0) - iod_from_json_(o, p); + iod_from_json_(s, o, p); else throw std::runtime_error("Empty string."); } @@ -527,7 +537,7 @@ namespace iod if (o.size() == 0) return; json_internals::json_parser p(str); if (str.size() > 0) - iod_from_json_(o, p); + iod_from_json_((sio*)0, o, p); else throw std::runtime_error("Empty string."); n_read = p.pos; @@ -539,7 +549,7 @@ namespace iod if (o.size() == 0) return; json_internals::json_parser p(str); if (str.size() > 0) - iod_from_json_(o, p); + iod_from_json_((sio*)0, o, p); else throw std::runtime_error("Empty string."); } @@ -550,7 +560,29 @@ namespace iod if (o.size() == 0) return; json_internals::json_parser p(stream); if (stream.str().size() > 0) - iod_from_json_(o, p); + iod_from_json_((sio*)0, o, p); + else + throw std::runtime_error("Empty string."); + } + + template + inline void json_decode(O& o, std::istringstream& stream) + { + if (o.size() == 0) return; + json_internals::json_parser p(stream); + if (stream.str().size() > 0) + iod_from_json_((S*)0, o, p); + else + throw std::runtime_error("Empty string."); + } + + template + inline void json_decode(O& o, const stringview& str) + { + if (S::size() == 0) return; + json_internals::json_parser p(str); + if (str.size() > 0) + iod_from_json_((S*)0, o, p); else throw std::runtime_error("Empty string."); } diff --git a/iod/linq_evaluate.hh b/iod/linq_evaluate.hh index 40e506c..3175966 100644 --- a/iod/linq_evaluate.hh +++ b/iod/linq_evaluate.hh @@ -73,7 +73,7 @@ namespace iod // Access to attributes of a named variable: variable[attribute] template inline auto - evaluate(const member_accessor_exp& s, const T& ctx) + evaluate(const array_subscript_exp& s, const T& ctx) { return M().member_access(evaluate(s.object, ctx)); } diff --git a/iod/sio.hh b/iod/sio.hh index 818bb06..47ee552 100644 --- a/iod/sio.hh +++ b/iod/sio.hh @@ -7,6 +7,7 @@ #include #include +#include namespace iod { @@ -103,7 +104,7 @@ namespace iod iod_foreach_runner::run(g, arg, tail...); } - struct attribute_not_found + struct member_not_found { typedef not_found symbol_type; typedef int value_type; @@ -129,113 +130,96 @@ namespace iod template not_found get_nth() const { return not_found(); } template - const attribute_not_found& get_nth_attribute() const { return *(attribute_not_found*)(0); } + const member_not_found& get_nth_attribute() const { return *(member_not_found*)(0); } template - attribute_not_found& get_nth_attribute() { return *(attribute_not_found*)(0); } + member_not_found& get_nth_attribute() { return *(member_not_found*)(0); } template D get(const E&, const D default_) const { return default_; } auto symbols_as_tuple() const { return std::make_tuple(); } }; - template - struct sio : public T, public sio + template + struct sio : public Ms... { - typedef sio self; - typedef sio super; - typedef std::tuple tuple_type; - - enum { _size = 1 + sizeof...(Tail), _empty = 0 }; + typedef sio self; + typedef std::tuple tuple_type; - template - struct _nth_attribute_ {}; + enum { _size = sizeof...(Ms), _empty = sizeof...(Ms) == 0 }; - template - struct _nth_attribute_> - { typedef typename std::tuple_element::type type; }; - - template - struct _nth_attribute_= _size)>> - { typedef attribute_not_found type; }; - - template - using _nth_attribute = typename _nth_attribute_>::type; + // Get the type of the nth member. + template + using nth_member_type = tl::get_nth_type; // ----------------------------------------- - // Retrive type of attribute with symbol S. + // Retrieve type of member with symbol S. // ----------------------------------------- - template - struct _attribute_; + template + struct _member_type_; - template - struct _attribute_<_size, C, S> + template + struct _member_type_<_size - 1, M, S, Sr, std::enable_if_t::value>> { - typedef attribute_not_found type; + typedef member_not_found type; }; - template - struct _attribute_ + template + struct _member_type_ { - typedef _nth_attribute type; + typedef M type; }; - - template - struct _attribute_ + + template + struct _member_type_::value)>> { - typedef typename _attribute_::symbol_type, S>::type type; + typedef nth_member_type Next; + typedef typename _member_type_::type type; }; - + template - using _attribute = typename _attribute_<0, typename _nth_attribute<0>::symbol_type, S>::type; + using symbol_to_member_type = typename _member_type_<0, nth_member_type<0>, + typename nth_member_type<0>::symbol_type, S>::type; + template - using attribute_value_type = typename _attribute_<0, typename _nth_attribute<0>::symbol_type, S>::type::value_type; + using member_value_type = typename symbol_to_member_type::value_type; - template - struct simple_enum { enum { value = V}; }; + // template + // struct simple_enum { enum { value = V}; }; - template - using _has = simple_enum, attribute_not_found>::value>; + template + using _has = std::integral_constant, member_not_found>::value>; // Constructor. inline sio() = default; + inline sio(Ms&&... members) : Ms(members)... {} + inline sio(const Ms&... members) : Ms(members)... {} - inline sio(const T&& attr, const Tail&&... tail) - : T(attr), - sio(std::forward(tail)...) - { - } - - inline sio(const T& attr, const Tail&... tail) - : T(attr), - sio(std::forward(tail)...) - { - } - - // Get the attribute associated with the symbol S. + // Get the member associated with the symbol S. + // Compile time complexity: O(N) template - auto& symbol_to_attribute(S = S()) + auto& symbol_to_member(S = S()) { - return *static_cast<_attribute*>(this); + return *static_cast*>(this); } template - const auto& symbol_to_attribute(S = S()) const + const auto& symbol_to_member(S = S()) const { - return *static_cast*>(this); + return *static_cast*>(this); } // Access to a member from a symbol. template auto& operator[](const E&) { - return symbol_to_attribute().value(); + return symbol_to_member().value(); } template const auto& operator[](const E&) const { - return symbol_to_attribute().value(); + return symbol_to_member().value(); } template @@ -270,42 +254,24 @@ namespace iod return _size == 0; } - // Access to the super attribute. - super& get_super() { return *this; } - const super& get_super() const { return *this; } - // Get the nth attribute. template - typename std::enable_if&>::type - get_nth_attribute() { return get_super().template get_nth_attribute(); } - + decltype(auto) get_nth_member() { return *static_cast*>(this); } template - typename std::enable_if&>::type - get_nth_attribute() { return *static_cast (this); } + decltype(auto) get_nth_member() const { return *static_cast*>(this); } template - typename std::enable_if&>::type - get_nth_attribute() const { return get_super().template get_nth_attribute(); } - - template - typename std::enable_if&>::type - get_nth_attribute() const { return *static_cast (this); } - - template - const typename _nth_attribute::value_type& - get_nth() const { return get_nth_attribute().value(); } + decltype(auto) + get_nth() const { return get_nth_member().value(); } template - typename _nth_attribute::value_type& - get_nth() { return get_nth_attribute().value(); } + decltype(auto) + get_nth() { return get_nth_member().value(); } - auto&& values_as_tuple() { return std::forward_as_tuple(static_cast(this)->value(), - static_cast(this)->value()...); } - auto&& values_as_tuple() const { return std::forward_as_tuple(static_cast(this)->value(), - static_cast(this)->value()...); } + auto&& values_as_tuple() { return std::forward_as_tuple(static_cast(this)->value()...); } + auto&& values_as_tuple() const { return std::forward_as_tuple(static_cast(this)->value()...); } - auto symbols_as_tuple() const { return std::make_tuple(static_cast(this)->symbol(), - static_cast(this)->symbol()...); } + auto symbols_as_tuple() const { return std::make_tuple(Ms::symbol()...); } // Assignment. template diff --git a/iod/sio_utils.hh b/iod/sio_utils.hh index 5fc0c59..3245f44 100644 --- a/iod/sio_utils.hh +++ b/iod/sio_utils.hh @@ -155,16 +155,37 @@ namespace iod return res; } - template - struct is_sio - { - template - static char test(sio*); - template - static int test(C*); - static const bool value = sizeof(test((std::decay_t*)0)) == 1; - }; + template + struct is_sio + { + template + static char test(sio*); + template + static int test(C*); + static const bool value = sizeof(test((std::decay_t*)0)) == 1; + }; + + template + struct is_tuple + { + template + static char test(std::tuple*); + template + static int test(C*); + static const bool value = sizeof(test((std::decay_t*)0)) == 1; + }; + + template + struct is_symbol + { + template + static char test(symbol*); + static int test(...); + static const bool value = sizeof(test((std::decay_t*)0)) == 1; + }; + + } // end of namespace iod. #include diff --git a/iod/symbol.hh b/iod/symbol.hh index 89df796..63254cc 100644 --- a/iod/symbol.hh +++ b/iod/symbol.hh @@ -10,7 +10,7 @@ namespace iod { template - struct symbol : public member_accessible, public callable, + struct symbol : public array_subscriptable, public callable, public assignable, public Exp { @@ -46,6 +46,7 @@ namespace iod typedef T value_type; \ typedef INFO attributes_type; \ typedef NAME##_t symbol_type; \ + typedef iod::variable> super; \ \ variable_type() {} \ template \ diff --git a/tests/core.cc b/tests/core.cc index f091be5..e00e8e7 100644 --- a/tests/core.cc +++ b/tests/core.cc @@ -18,6 +18,10 @@ int main() using namespace s; { auto o = D(_name = "John", _age = 12); + + static_assert(!std::is_same(), member_not_found>::value, ""); + static_assert(std::is_same, member_not_found>::value, ""); + assert(o.name == "John"); assert(o.age == 12); diff --git a/tests/json.cc b/tests/json.cc index 8dc70fb..f3ac34b 100644 --- a/tests/json.cc +++ b/tests/json.cc @@ -11,7 +11,7 @@ int main() { using namespace iod; using namespace s; - + { auto o = D(_name = "John", _age = 12, _children = { 1,2,3,4,5 }, _city = D(_name = "Paris")); auto str = json_encode(o); @@ -59,4 +59,18 @@ int main() } + // Decode with scheme. + { + typedef decltype(D(_name(_json_key = _username) = std::string(), + _age = int(), + _city = std::string())) user_scheme; + + struct { std::string name, city; int age; } custom_user; + + std::string str = R"({"username":"John","age":12,"city":"NYC"})"; + + json_decode(custom_user, str); + + std::cout << custom_user.name << " " << custom_user.age << " " << custom_user.city << std::endl; + } } From 7b3c2e1bad4322a69756d25c61cb4ff2ac4491e0 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 5 Jan 2016 11:04:58 +0100 Subject: [PATCH 26/94] Add type_list_utils. --- iod/type_list_utils.hh | 84 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 iod/type_list_utils.hh diff --git a/iod/type_list_utils.hh b/iod/type_list_utils.hh new file mode 100644 index 0000000..376a87a --- /dev/null +++ b/iod/type_list_utils.hh @@ -0,0 +1,84 @@ +#pragma once + +namespace iod +{ + namespace tl + { + + namespace detail + { + + template struct seq{ using type = seq; }; + + template struct concat; + + template + struct concat, seq> + : seq{}; + + template + using concat_t = typename concat::type; + + template struct gen_seq; + template using gen_seq_t = typename gen_seq::type; + + template + struct gen_seq : concat_t, gen_seq_t>{}; + + template<> struct gen_seq<0> : seq<>{}; + template<> struct gen_seq<1> : seq<0>{}; + + template + struct eat + { + template + eat(T) {} + }; + + template + struct get_nth_helper + { + template + static decltype(auto) run(detail::eat..., T e, Tail&&...) + { + return e; + } + }; + + template + decltype(auto) get_nth_impl(seq seq, T&&... l) + { + return get_nth_helper::run(std::forward(l)...); + } + + } + + template + decltype(auto) get_nth(T&&... l) + { + return detail::get_nth_impl(detail::gen_seq_t{}, std::forward(l)...); + } + + template + using get_nth_type = decltype(get_nth(std::declval()...)); + + //find_first. + template + auto find_first(F pred, T1 e, T&&... l) + { + if (pred()) + return e; + else find_first(pred, l...); + } + + template + auto find_first(F pred) + { + return not_found(); + } + + } + + using tl::detail::gen_seq_t; + +} From 24b2d5942a115e22bb892d4fc2019a8e1fce66bf Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Thu, 28 Jan 2016 13:34:50 +0100 Subject: [PATCH 27/94] Add deep_merge and tuple_minus. --- iod/foreach.hh | 43 ++++++++++++++++++++++++++++++++++++++++--- iod/sio_utils.hh | 37 +++++++++++++++++++++++++++++++++++++ iod/tuple_utils.hh | 10 ++++++++++ tests/CMakeLists.txt | 4 ++++ tests/deep_merge.cc | 23 +++++++++++++++++++++++ 5 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 tests/deep_merge.cc diff --git a/iod/foreach.hh b/iod/foreach.hh index 60732e1..556be34 100644 --- a/iod/foreach.hh +++ b/iod/foreach.hh @@ -21,9 +21,7 @@ namespace iod decltype(auto) foreach_loop_tuple(std::enable_if_t*, F, A&&, R&&... results) { - return static_if( - [] () {}, - [&] () { return std::make_tuple(results...);}); + return std::make_tuple(results...); } template @@ -244,4 +242,43 @@ namespace iod // return internal::foreach_loop_sio<0, sizeof...(S)>(0, f, std::forward_as_tuple(a1, args...)); // } + template + inline + auto + sio_iterate_loop(std::enable_if_t*, F f, const O& o, const P& prev) + { + auto new_prev = f(o.template get_nth_member(), prev); + return sio_iterate_loop(0, f, o, new_prev); + } + + template + inline + auto + sio_iterate_loop(std::enable_if_t*, F f, const O& o, const P& prev) + { + return prev; + } + + template + struct sio_iterate_caller + { + sio_iterate_caller(O o, P init) : o_(o), init_(init) {} + + template + auto operator|(F f) + { + const int size = O::size(); + return sio_iterate_loop<0, size>(0, f, o_, init_); + } + + const O o_; + P init_; + }; + + template + auto sio_iterate(O o, I init) + { + return sio_iterate_caller(o, init); + } + } diff --git a/iod/sio_utils.hh b/iod/sio_utils.hh index 3245f44..8c2d81f 100644 --- a/iod/sio_utils.hh +++ b/iod/sio_utils.hh @@ -7,6 +7,8 @@ #include #include +#include +#include #include namespace iod @@ -184,7 +186,42 @@ namespace iod static int test(...); static const bool value = sizeof(test((std::decay_t*)0)) == 1; }; + + template + auto deep_merge_2_sios(S1 s1, S2 s2) { return s1; } + template + auto deep_merge_2_sios(member_not_found s1, S2 s2) { return s2; } + template + auto deep_merge_2_sios(S1 s1, member_not_found s2) { return s1; } + + template + auto deep_merge_2_sios(sio s1, sio s2) + { + auto symbols1 = s1.symbols_as_tuple(); + auto symbols2 = s2.symbols_as_tuple(); + + using symbols_t = typename tuple_minus, std::decay_t>::type; + auto t = foreach(std::tuple_cat(symbols_t(), symbols2)) | [&] (auto s) + { + return s = deep_merge_2_sios(s1.get(s, member_not_found()), s2.get(s, member_not_found())); + }; + + return iod::apply(t, D_caller()); + } + + template + auto deep_merge_sios_in_tuple_rec(const std::tuple, O...>& t) + { + return static_if<(I < sizeof...(O))>( + [](const auto& t){ return deep_merge_2_sios(std::get(t), deep_merge_sios_in_tuple_rec(t)); }, + [](const auto& t){ return std::get(t); }, t); + } + template + auto deep_merge_sios_in_tuple(const std::tuple, O...>& t) + { + return deep_merge_sios_in_tuple_rec<0>(t); + } } // end of namespace iod. diff --git a/iod/tuple_utils.hh b/iod/tuple_utils.hh index 42baf0a..49c1ff7 100644 --- a/iod/tuple_utils.hh +++ b/iod/tuple_utils.hh @@ -115,6 +115,16 @@ namespace iod typedef std::tuple type; }; + + template + struct tuple_minus; + + template + struct tuple_minus, std::tuple> + { + typedef typename tuple_remove_elements, R...>::type type; + }; + template using tuple_remove_elements_t = typename tuple_remove_elements::type; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 81d70c6..5ed2312 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -40,3 +40,7 @@ add_test(bind_method bind_method) add_executable(tuple tuple.cc) add_test(tuple tuple) + + +add_executable(deep_merge deep_merge.cc) +add_test(deep_merge deep_merge) diff --git a/tests/deep_merge.cc b/tests/deep_merge.cc new file mode 100644 index 0000000..3c987d1 --- /dev/null +++ b/tests/deep_merge.cc @@ -0,0 +1,23 @@ +#include +#include +#include +#include "symbols.hh" + +int main() +{ + using namespace iod; + auto a = D(_age = 1, + _c = 23, + _name = D(_a = 23)); + auto b = D(_age = 42, + _cp = 23, + _name = D(_b = 23)); + + + auto c = deep_merge_2_sios(a, b); + //auto d = iod::apply(std::make_tuple(a, b), deep_merge_2_sios); + //auto d = iod::apply(a, b, [] (auto a, auto b) { deep_merge_2_sios(a, b); }); + //auto d = iod::apply(std::make_tuple(a, b), [] (auto a, auto b) { return deep_merge_2_sios(a, b); }); + auto d = deep_merge_sios_in_tuple(std::make_tuple(a, b)); + std::cout << json_encode(d) << std::endl; +} From 3189be875949c04e6c042e88f07af991e9d546c9 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Sun, 14 Feb 2016 11:15:38 +0100 Subject: [PATCH 28/94] Remove biicode build. --- CMakeLists.txt | 47 ++++++++++++++++----------------------------- bii/.hive.db | Bin 240640 -> 0 bytes bii/layout.bii | 12 ------------ bii/policies.bii | 49 ----------------------------------------------- bii/settings.bii | 2 -- biicode.conf | 37 ----------------------------------- 6 files changed, 16 insertions(+), 131 deletions(-) delete mode 100644 bii/.hive.db delete mode 100644 bii/layout.bii delete mode 100644 bii/policies.bii delete mode 100644 bii/settings.bii delete mode 100644 biicode.conf diff --git a/CMakeLists.txt b/CMakeLists.txt index 0eefc23..8ddda70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,3 @@ -IF(BIICODE) - - ADD_BIICODE_TARGETS() - -IF(APPLE) - TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE "-std=c++14 -stdlib=libc++") -ELSEIF (WIN32 OR UNIX) - TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE "-std=c++14") -ENDIF(APPLE) - -ELSE() - - cmake_minimum_required(VERSION 2.8) project(Iod) @@ -24,27 +11,25 @@ install(DIRECTORY iod DESTINATION include add_subdirectory(tools) add_subdirectory(tests) -#set(IOD_INCLUDE_DIR "include") -#set(CMAKE_CONFIG_DEST "share/iod") +set(IOD_INCLUDE_DIR "include") +set(CMAKE_CONFIG_DEST "share/iod") -#include(CMakePackageConfigHelpers) -#configure_package_config_file ( -# ${CMAKE_SOURCE_DIR}/IodConfig.cmake.in -# ${CMAKE_BINARY_DIR}/IodConfig.cmake -# INSTALL_DESTINATION ${CMAKE_CONFIG_DEST} -# PATH_VARS IOD_INCLUDE_DIR CMAKE_CONFIG_DEST) +include(CMakePackageConfigHelpers) +configure_package_config_file ( + ${CMAKE_SOURCE_DIR}/IodConfig.cmake.in + ${CMAKE_BINARY_DIR}/IodConfig.cmake + INSTALL_DESTINATION ${CMAKE_CONFIG_DEST} + PATH_VARS IOD_INCLUDE_DIR CMAKE_CONFIG_DEST) -#export(PACKAGE Iod) +export(PACKAGE Iod) -#configure_file(IodConfigVersion.cmake.in -# "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" @ONLY) +configure_file(IodConfigVersion.cmake.in + "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" @ONLY) -#install(FILES -# "${PROJECT_BINARY_DIR}/IodConfig.cmake" -# "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" -# DESTINATION share/iod) +install(FILES + "${PROJECT_BINARY_DIR}/IodConfig.cmake" + "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" + DESTINATION share/iod) # Install the export set for use with the install-tree -#install(EXPORT IodTargets DESTINATION ${CMAKE_CONFIG_DEST}) - -ENDIF() # BIICODE +install(EXPORT IodTargets DESTINATION ${CMAKE_CONFIG_DEST}) diff --git a/bii/.hive.db b/bii/.hive.db deleted file mode 100644 index 73a984d9bcd936a875e20ae56eb2ccfb9a8ee439..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 240640 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 - priority: 1 - -# For all other users only accept STABLE blocks -- block: ALL - version: tag==STABLE - priority: 1 - -# Examples: -# Let's say that you (maya) introduce a dependency to some cell in willy/block and -# you want to reuse as a Beta tester of such block, you should write a new rule: -#- block: block == "willy/block" -# version: tag>=BETA -# priority: 1 -# -# If you want to accept all ALPHA VERSIONS of another user's published -# blocks with priority 1. -#- block: block.user == "ANOTHER_USER" -# version: tag==ALPHA -# priority: 1 - - - diff --git a/bii/settings.bii b/bii/settings.bii deleted file mode 100644 index 9989d31..0000000 --- a/bii/settings.bii +++ /dev/null @@ -1,2 +0,0 @@ -cmake: {generator: Unix Makefiles} -os: {arch: 64bit, family: Linux} diff --git a/biicode.conf b/biicode.conf deleted file mode 100644 index c52b801..0000000 --- a/biicode.conf +++ /dev/null @@ -1,37 +0,0 @@ -# Biicode configuration file - -[requirements] - - -[parent] - matt42/iod: 0 -[paths] - # Local directories to look for headers (within block) - / - # include - -[dependencies] - # Manual adjust file implicit dependencies, add (+), remove (-), or overwrite (=) - # hello.h + hello_imp.cpp hello_imp2.cpp - # *.h + *.cpp - -[mains] - !* # Nothing to compile - -[tests] - -[hooks] - # These are defined equal to [dependencies],files names matching bii*stage*hook.py - # will be launched as python scripts at stage = {post_process, clean} - # CMakeLists.txt + bii/my_post_process1_hook.py bii_clean_hook.py - -[includes] - # Mapping of include patterns to external blocks - # hello*.h: user3/depblock # includes will be processed as user3/depblock/hello*.h - -[data] - # Manually define data files dependencies, that will be copied to bin for execution - # By default they are copied to bin/user/block/... which should be taken into account - # when loading from disk such data - # image.cpp + image.jpg # code should write open("user/block/image.jpg") - From dea5fa83e4a6f30af9f6f23bfe4324e017d4ecd0 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Mon, 15 Feb 2016 19:59:30 +0100 Subject: [PATCH 29/94] Optimize json encoder. --- iod/json.hh | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/iod/json.hh b/iod/json.hh index af9a5e7..d4472f9 100644 --- a/iod/json.hh +++ b/iod/json.hh @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,22 @@ namespace iod namespace json_internals { + struct my_ostringstream + { + my_ostringstream() { str_.reserve(20); } + + template + my_ostringstream& operator<<(const T& t) { str_ += boost::lexical_cast(t); return *this; } + + my_ostringstream& operator<<(const std::string& t) { str_.append(t); return *this; } + my_ostringstream& operator<<(const char t) { str_.append(&t, 1); return *this; } + my_ostringstream& operator<<(const char* t) { str_.append(t); return *this; } + my_ostringstream& operator<<(const boost::string_ref& t) { str_.append(&t[0], t.size()); return *this; } + + const std::string& str() { return str_; } + std::string str_; + }; + // Json encoder. // ============================================= template @@ -66,6 +83,14 @@ namespace iod ss << s.str[i]; ss << '"'; } + + template + inline void json_encode_(const boost::string_ref& s, S& ss) + { + ss << '"'; + ss << s; + ss << '"'; + } template inline void json_encode_(const std::string& t, S& ss) @@ -590,7 +615,7 @@ namespace iod template inline std::string json_encode(const sio& o) { - std::stringstream ss; + json_internals::my_ostringstream ss; json_internals::json_encode_(o, ss); return ss.str(); } From 11aa17a6186189b968810edd3e1e6cae76a5c99f Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Tue, 8 Mar 2016 23:27:04 +0100 Subject: [PATCH 30/94] Speedup compilation of di by 30%. --- iod/di.hh | 149 +++++++++++++++++++++------------------------ iod/tuple_utils.hh | 75 +++++++++-------------- tests/di.cc | 19 ++++++ 3 files changed, 118 insertions(+), 125 deletions(-) diff --git a/iod/di.hh b/iod/di.hh index a056dfe..84715dc 100644 --- a/iod/di.hh +++ b/iod/di.hh @@ -59,7 +59,6 @@ namespace iod template using tuple_filter_references_t = typename tuple_filter_references::type; - template decltype(auto) call_factory_instantiate(M& factory, C&& ctx, std::tuple*) { @@ -100,45 +99,45 @@ namespace iod template using dependencies_of = dependencies_of_>; - // tuple_iterate provides an iteration on a tuple with knowledge of the - // return value of the previous loop step. - template - inline - auto - tuple_iterate_loop(std::enable_if_t*, F, A&&, P&& prev) - { - return prev; - } + // // tuple_iterate provides an iteration on a tuple with knowledge of the + // // return value of the previous loop step. + // template + // inline + // auto + // tuple_iterate_loop(std::enable_if_t*, F, A&&, P&& prev) + // { + // return prev; + // } - template - inline - auto - tuple_iterate_loop(std::enable_if_t*, F f, A&& t, P&& prev) - { - return tuple_iterate_loop(0, f, t, f(std::get(t), prev)); - } - - template - struct tuple_iterate_caller - { - tuple_iterate_caller(T&& t, P&& prev_init) : t_(t), prev_init_(prev_init) {} - - template - auto operator|(F f) - { - const int size = std::tuple_size>::value; - return tuple_iterate_loop<0, size>(0, f, t_, prev_init_); - } - - const T t_; - P prev_init_; - }; + // template + // inline + // auto + // tuple_iterate_loop(std::enable_if_t*, F f, A&& t, P&& prev) + // { + // return tuple_iterate_loop(0, f, t, f(std::get(t), prev)); + // } + + // template + // struct tuple_iterate_caller + // { + // tuple_iterate_caller(T&& t, P&& prev_init) : t_(t), prev_init_(prev_init) {} + + // template + // auto operator|(F f) + // { + // const int size = std::tuple_size>::value; + // return tuple_iterate_loop<0, size>(0, f, t_, prev_init_); + // } + + // const T t_; + // P prev_init_; + // }; - template - auto tuple_iterate(T&& t, C&& init) - { - return tuple_iterate_caller(t, init); - } + // template + // auto tuple_iterate(T&& t, C&& init) + // { + // return tuple_iterate_caller(t, init); + // } template struct has_instantiate_static_method @@ -151,7 +150,7 @@ namespace iod static const int value = (sizeof(test>(0)) == sizeof(char)); }; - + template typename T::factory_type return_factory_type(int x, typename T::factory_type* = 0); template @@ -187,31 +186,25 @@ namespace iod template using find_di_factory_t = std::remove_reference_t>::type>; - + + // Provide an element of type E: // If \to_inject contains an element of type E, return it. // If \to_inject contains an element f and f.instantiate return type is E, // return f.instantiate(...). Note: \to_inject must contains the arguments of f::instantiate. // Otherwise, call the static method E::instantiate. - struct X {}; template decltype(auto) di_meta_instantiate(T&& to_inject, F f) { - typedef std::remove_reference_t T2; + typedef std::decay_t T2; typedef std::remove_const_t> E2; - return static_if::value or - tuple_embeds::value or - tuple_embeds::value or - tuple_embeds::value or - tuple_embeds::value or - tuple_embeds::value - >( + return static_if::value>( [&] (auto& to_inject) -> decltype(auto) { // If to_inject already embeds an element of type E, return it. - auto instantiate = [&] (auto) -> decltype(auto) { - return tuple_get_by_type(to_inject); }; + auto instantiate = [&] (auto ctx) -> decltype(auto) { + return tuple_get_by_type(ctx); }; return f(instantiate, (std::tuple<>*)0); }, [&] (auto& to_inject) -> decltype(auto) { @@ -219,22 +212,22 @@ namespace iod typedef find_di_factory_t FT; return iod::static_if::value>( // If to_inject embed a factory, call it. - [&] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { + [f] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { typedef std::remove_pointer_t FT_; typedef iod::callable_arguments_tuple_t ARGS; auto instantiate = [&] (auto&& ctx) -> decltype(auto) { - return call_factory_instantiate(tuple_get_by_type(deps), ctx, (ARGS*)0); + return call_factory_instantiate(tuple_get_by_type(ctx), ctx, (ARGS*)0); }; return f(instantiate, (ARGS*)0); }, // If the argument type provide a static instantiate method, call it. - [&] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { + [f] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { typedef std::remove_pointer_t> E2; static_assert(has_instantiate_static_method::value, "Dependency injection failed. Cannot resolve."); typedef iod::callable_arguments_tuple_t ARGS; - auto instantiate = [&] (auto& ctx) { return call_factory_instantiate_static>(ctx, (ARGS*)0); }; + auto instantiate = [&] (auto&& ctx) { return call_factory_instantiate_static>(ctx, (ARGS*)0); }; return f(instantiate, (ARGS*)0); }, to_inject, (E2*)0, (FT*)0); @@ -275,9 +268,7 @@ namespace iod template static decltype(auto) run(P&& prev) { - typedef std::remove_reference_t(prev))> D; - D& d = *(D*)0; - return create_di_ctx_iterator::template run(d); + return create_di_ctx_iterator::template run(create_di_ctx_rec(prev)); } }; @@ -289,30 +280,33 @@ namespace iod { return create_di_ctx_iterator::template run(ctx); } - + template decltype(auto) create_di_ctx_rec(T&& ctx) { - return di_meta_instantiate(ctx, - [&] (auto instantiate, auto args) -> decltype(auto) - { - auto& ctx2 = ctx; // Fix to import ctx in the closure with gcc 4.9. - typedef std::remove_pointer_t ARGS; - typedef - std::remove_reference_t D; - D& deps = *(D*)0; - return std::tuple_cat(deps, forward_as_tuple_no_rvalue(instantiate(deps))); - }); + return static_if, E>::value>( + [] (auto ctx) { return ctx; }, + [] (auto ctx) { + return di_meta_instantiate(ctx, + [&] (auto instantiate, auto args) -> decltype(auto) + { + typedef std::remove_pointer_t ARGS; + auto deps = create_di_ctx_list_rec(ctx, (ARGS*)0); + return std::tuple_cat(deps, forward_as_tuple_no_rvalue(instantiate(deps))); + }); + }, ctx); } - template + + + template decltype(auto) create_stack_and_call(std::tuple<>*, std::tuple*, F fun, B&&... to_inject) { return fun(tuple_get_by_type(std::forward_as_tuple(to_inject...))...); } - + template decltype(auto) create_stack_and_call(std::tuple*, std::tuple* args, @@ -324,27 +318,22 @@ namespace iod } - // Call fun with its required argument A... // by picking in args... or calling A::instantiate() template - auto call_with_di2(F fun, std::tuple* arguments, B&&... to_inject) + typename callable_traits::return_type + call_with_di2(F fun, std::tuple* arguments, B&&... to_inject) { // Compute the context type containing the arguments plus the // dependencies of the possible A::instantiate(...) methods. typedef std::remove_reference_t< decltype(create_di_ctx_list_rec( - std::declval...>>(), + std::declval>(), arguments)) > ctx_type; - // Remove the rvalues references to be able to store the context. - typedef tuple_remove_rvalues_t ctx_type2; - //typedef tuple_filter_references_t ctx_type3; - - //void* x = *(ctx_type3*)0; - return create_stack_and_call((ctx_type2*)0, (std::tuple*)0, fun, to_inject...); + return create_stack_and_call((ctx_type*)0, (std::tuple*)0, fun, to_inject...); } } diff --git a/iod/tuple_utils.hh b/iod/tuple_utils.hh index 49c1ff7..1fc7b57 100644 --- a/iod/tuple_utils.hh +++ b/iod/tuple_utils.hh @@ -2,64 +2,49 @@ #include #include - +#include "utils.hh" namespace iod { - template - struct tuple_find_type2; - - // template - // struct tuple_find_type2, X> : public std::integral_constant {}; - template - struct tuple_find_type2, X> : public not_found {}; - - template - struct tuple_find_type2, X> : public std::integral_constant {}; - template - struct tuple_find_type2, X> : public std::integral_constant {}; - template - struct tuple_find_type2, X> : public std::integral_constant {}; - template - struct tuple_find_type2, X> : public std::integral_constant {}; - template - struct tuple_find_type2, X> : public std::integral_constant {}; - - template - struct tuple_find_type2, X&> : public std::integral_constant {}; - template - struct tuple_find_type2, X&&> : public std::integral_constant {}; - template - struct tuple_find_type2, const X&> : public std::integral_constant {}; - template - struct tuple_find_type2, const X> : public std::integral_constant {}; - - template - struct tuple_find_type2, X> : public tuple_find_type2, X> {}; - template - struct tuple_find_type : public tuple_find_type2<0, T, X> {}; + constexpr int count_first_falses() { return 0; } + + template + constexpr int count_first_falses(bool b1, B... b) + { + if (b1) return 0; + else return 1 + count_first_falses(b...); + } - template - auto& tuple_get_by_type(T&& tuple) + template + decltype(auto) tuple_get_by_type(std::tuple& tuple) { - return std::get>, - std::remove_const_t>>::value>(tuple); + typedef std::decay_t DE; + return std::get, DE>::value)...)>(tuple); } + template + decltype(auto) tuple_get_by_type(std::tuple&& tuple) + { + typedef std::decay_t DE; + return std::get, DE>::value)...)>(tuple); + } + + template struct tuple_embeds : public std::false_type {}; - template - struct tuple_embeds, U> : public std::false_type {}; - - template - struct tuple_embeds, T1> : public std::true_type {}; - - template - struct tuple_embeds, U> : public tuple_embeds, U> {}; + template + struct tuple_embeds, U> : + public std::integral_constant::value...) != sizeof...(T)> + {}; + template + struct tuple_embeds_any_ref_of : public std::false_type {}; + template + struct tuple_embeds_any_ref_of, U> : public tuple_embeds...>, std::decay_t> {}; + template struct tuple_remove_references; diff --git a/tests/di.cc b/tests/di.cc index 6d17429..e583bb2 100644 --- a/tests/di.cc +++ b/tests/di.cc @@ -167,6 +167,18 @@ struct with_data_instance2 }; +struct with_data_instance3 +{ + + static with_data_instance3 instantiate(with_data& wd) { + std::cout << "instantiate3 " << wd.s << std::endl; + return with_data_instance3{wd}; + } + + with_data& w; +}; + + void fun9(with_data_instance& wd) { std::cout << "fun9: " << wd.s << std::endl; @@ -183,6 +195,9 @@ int main() float x = 1; int y = 2; + // auto t= std::make_tuple([&] () -> decltype(auto) { return y; }); + // typedef decltype(t) T2; + // static_assert(iod::di::tuple_embeds_fun_with_return_type::value, ""); iod::di_call(&fun1); iod::di_call(&fun1, 1); iod::di_call(&fun2, 1); @@ -219,4 +234,8 @@ int main() // test reference. auto f3 = [] (int& x) { assert(&x == &mref_int); }; iod::di_call(f3, Mref()); + + + auto f4 = [] (with_data_instance2, with_data_instance3) {}; + iod::di_call(f4, wd); } From 0f0159d34a582ae1e80e7233944b52e8c7ed8e1a Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Wed, 9 Mar 2016 22:02:01 +0100 Subject: [PATCH 31/94] Speedup compilation of DI with typelist and other compile time optimisation. --- iod/callable_traits.hh | 10 ++ iod/di.hh | 204 ++++++++++++----------------------------- iod/tuple_utils.hh | 45 ++++++++- iod/typelist.hh | 58 ++++++++++++ 4 files changed, 169 insertions(+), 148 deletions(-) create mode 100644 iod/typelist.hh diff --git a/iod/callable_traits.hh b/iod/callable_traits.hh index 06608be..acba1da 100644 --- a/iod/callable_traits.hh +++ b/iod/callable_traits.hh @@ -1,5 +1,7 @@ #pragma once +#include "typelist.hh" + namespace iod { namespace internal @@ -28,6 +30,7 @@ namespace iod typedef std::false_type is_callable; static const int arity = 0; typedef std::tuple<> arguments_tuple; + typedef typelist<> arguments_list; typedef void return_type; }; @@ -45,6 +48,7 @@ namespace iod typedef std::true_type is_callable; static const int arity = super::arity; typedef typename super::arguments_tuple arguments_tuple; + typedef typename super::arguments_list arguments_list; typedef typename super::return_type return_type; }; @@ -54,6 +58,7 @@ namespace iod typedef std::true_type is_callable; static const int arity = sizeof...(ARGS); typedef std::tuple arguments_tuple; + typedef typelist arguments_list; typedef R return_type; }; @@ -63,6 +68,7 @@ namespace iod typedef std::true_type is_callable; static const int arity = sizeof...(ARGS); typedef std::tuple arguments_tuple; + typedef typelist arguments_list; typedef R return_type; }; @@ -72,6 +78,7 @@ namespace iod typedef std::true_type is_callable; static const int arity = sizeof...(ARGS); typedef std::tuple arguments_tuple; + typedef typelist arguments_list; typedef R return_type; }; @@ -82,12 +89,15 @@ namespace iod typedef std::true_type is_callable; static const int arity = sizeof...(ARGS); typedef std::tuple arguments_tuple; + typedef typelist arguments_list; typedef R return_type; }; template using callable_arguments_tuple_t = typename callable_traits::arguments_tuple; template + using callable_arguments_list_t = typename callable_traits::arguments_list; + template using callable_return_type_t = typename callable_traits::return_type; template diff --git a/iod/di.hh b/iod/di.hh index 84715dc..173ee0e 100644 --- a/iod/di.hh +++ b/iod/di.hh @@ -13,60 +13,14 @@ namespace iod namespace di { - template - struct remove_rvalue_reference { typedef T type; }; - template - struct remove_rvalue_reference { typedef T type; }; - - template - using remove_rvalue_reference_t = typename remove_rvalue_reference::type; - - template - struct tuple_remove_rvalues; - template - struct tuple_remove_rvalues > - { - typedef std::tuple::type...> type; - }; - - template - using tuple_remove_rvalues_t = typename tuple_remove_rvalues::type; - - template - decltype(auto) forward_as_tuple_no_rvalue(T&&... t) - { - return std::tuple...>(std::forward(t)...); - } - - template - struct tuple_filter_references - { - typedef T type; - }; - - template - struct tuple_filter_references> - { - typedef typename tuple_filter_references>::type type; - }; - - template - struct tuple_filter_references > - { - typedef decltype(std::tuple_cat(std::declval>(), - std::declval>::type>())) type; - }; - - template - using tuple_filter_references_t = typename tuple_filter_references::type; template - decltype(auto) call_factory_instantiate(M& factory, C&& ctx, std::tuple*) + decltype(auto) call_factory_instantiate(M& factory, C&& ctx, typelist*) { return factory.instantiate(std::forward(tuple_get_by_type(ctx))...); } template - decltype(auto) call_factory_instantiate_static(C&& ctx, std::tuple*) + decltype(auto) call_factory_instantiate_static(C&& ctx, typelist*) { return std::decay_t::instantiate(std::forward(tuple_get_by_type(ctx))...); } @@ -99,46 +53,6 @@ namespace iod template using dependencies_of = dependencies_of_>; - // // tuple_iterate provides an iteration on a tuple with knowledge of the - // // return value of the previous loop step. - // template - // inline - // auto - // tuple_iterate_loop(std::enable_if_t*, F, A&&, P&& prev) - // { - // return prev; - // } - - // template - // inline - // auto - // tuple_iterate_loop(std::enable_if_t*, F f, A&& t, P&& prev) - // { - // return tuple_iterate_loop(0, f, t, f(std::get(t), prev)); - // } - - // template - // struct tuple_iterate_caller - // { - // tuple_iterate_caller(T&& t, P&& prev_init) : t_(t), prev_init_(prev_init) {} - - // template - // auto operator|(F f) - // { - // const int size = std::tuple_size>::value; - // return tuple_iterate_loop<0, size>(0, f, t_, prev_init_); - // } - - // const T t_; - // P prev_init_; - // }; - - // template - // auto tuple_iterate(T&& t, C&& init) - // { - // return tuple_iterate_caller(t, init); - // } - template struct has_instantiate_static_method { @@ -200,51 +114,48 @@ namespace iod typedef std::decay_t T2; typedef std::remove_const_t> E2; - return static_if::value>( - [&] (auto& to_inject) -> decltype(auto) { - // If to_inject already embeds an element of type E, return it. - auto instantiate = [&] (auto ctx) -> decltype(auto) { - return tuple_get_by_type(ctx); }; - return f(instantiate, (std::tuple<>*)0); - }, - [&] (auto& to_inject) -> decltype(auto) { - - typedef find_di_factory_t FT; - return iod::static_if::value>( - // If to_inject embed a factory, call it. - [f] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { - typedef std::remove_pointer_t FT_; - typedef iod::callable_arguments_tuple_t ARGS; - auto instantiate = [&] (auto&& ctx) -> decltype(auto) - { - return call_factory_instantiate(tuple_get_by_type(ctx), ctx, (ARGS*)0); - }; - return f(instantiate, (ARGS*)0); - }, - // If the argument type provide a static instantiate method, call it. - [f] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { - typedef std::remove_pointer_t> E2; - static_assert(has_instantiate_static_method::value, - "Dependency injection failed. Cannot resolve."); - typedef iod::callable_arguments_tuple_t ARGS; - auto instantiate = [&] (auto&& ctx) { return call_factory_instantiate_static>(ctx, (ARGS*)0); }; - return f(instantiate, (ARGS*)0); - }, - to_inject, (E2*)0, (FT*)0); - }, - to_inject); + typedef find_di_factory_t FT; + return iod::static_if::value>( + // If to_inject embed a factory, call it. + [f] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { + typedef std::remove_pointer_t FT_; + typedef iod::callable_arguments_list_t ARGS; + auto instantiate = [&] (auto&& ctx) -> decltype(auto) + { + return call_factory_instantiate(tuple_get_by_type(ctx), ctx, (ARGS*)0); + }; + return f(instantiate, (ARGS*)0); + }, + // If the argument type provide a static instantiate method, call it. + [f] (auto&& deps, auto* e, auto* ft_) -> decltype(auto) { + typedef std::remove_pointer_t> E2; + static_assert(has_instantiate_static_method::value, + "Dependency injection failed. Cannot resolve."); + typedef iod::callable_arguments_list_t ARGS; + auto instantiate = [&] (auto&& ctx) -> decltype(auto) { return call_factory_instantiate_static>(ctx, (ARGS*)0); }; + return f(instantiate, (ARGS*)0); + }, + to_inject, (E2*)0, (FT*)0); } - template - decltype(auto) instantiate(T&& to_inject) + template + decltype(auto) instantiate(std::enable_if_t, E>::value>*, + T&&... to_inject) { - return di_meta_instantiate(to_inject, + return di_meta_instantiate(std::forward_as_tuple(to_inject...), [&] (auto instantiate, auto* args) -> decltype(auto) - { - return instantiate(to_inject); - }); - } + { + return instantiate(std::forward_as_tuple(to_inject...)); + }); + } + template + decltype(auto) instantiate(std::enable_if_t, E>::value>*, + T&&... to_inject) + { + return arg_get_by_type(std::forward(to_inject)...); + } + template decltype(auto) create_di_ctx_rec(T&& ctx); @@ -276,7 +187,7 @@ namespace iod // returns the concatenation of ctx, elements of type A... and // the elements required to build them. template - decltype(auto) create_di_ctx_list_rec(C&& ctx, std::tuple*) + decltype(auto) create_di_ctx_list_rec(C&& ctx, typelist*) { return create_di_ctx_iterator::template run(ctx); } @@ -284,44 +195,42 @@ namespace iod template decltype(auto) create_di_ctx_rec(T&& ctx) { - return static_if, E>::value>( - [] (auto ctx) { return ctx; }, - [] (auto ctx) { - return di_meta_instantiate(ctx, + return static_if, E>::value>( + [] (auto&& ctx) { return ctx; }, + [] (auto&& ctx) { + return di_meta_instantiate(*(typelist_to_tuple_t>*)0, [&] (auto instantiate, auto args) -> decltype(auto) { typedef std::remove_pointer_t ARGS; auto deps = create_di_ctx_list_rec(ctx, (ARGS*)0); - return std::tuple_cat(deps, forward_as_tuple_no_rvalue(instantiate(deps))); + return typelist_cat(deps, typelist()); }); }, ctx); } - - template - decltype(auto) create_stack_and_call(std::tuple<>*, - std::tuple*, + decltype(auto) create_stack_and_call(typelist<>*, + typelist*, F fun, B&&... to_inject) { - return fun(tuple_get_by_type(std::forward_as_tuple(to_inject...))...); + return fun(arg_get_by_type(std::forward(to_inject)...)...); } template - decltype(auto) create_stack_and_call(std::tuple*, - std::tuple* args, + decltype(auto) create_stack_and_call(typelist*, + typelist* args, F fun, B&&... to_inject) { - return create_stack_and_call((std::tuple*)0, args, fun, + return create_stack_and_call((typelist*)0, args, fun, std::forward(to_inject)..., - instantiate(std::forward_as_tuple(to_inject...))); + instantiate(0, std::forward(to_inject)...)); } // Call fun with its required argument A... // by picking in args... or calling A::instantiate() template - typename callable_traits::return_type + decltype(auto) call_with_di2(F fun, std::tuple* arguments, B&&... to_inject) { // Compute the context type containing the arguments plus the @@ -329,11 +238,12 @@ namespace iod typedef std::remove_reference_t< decltype(create_di_ctx_list_rec( - std::declval>(), - arguments)) + std::declval>(), + (typelist*)0)) > ctx_type; - return create_stack_and_call((ctx_type*)0, (std::tuple*)0, fun, to_inject...); + // typedef typename tuple_to_list::type ctx_typelist; + return create_stack_and_call((ctx_type*)0, (typelist*)0, fun, to_inject...); } } diff --git a/iod/tuple_utils.hh b/iod/tuple_utils.hh index 1fc7b57..b9d0ccf 100644 --- a/iod/tuple_utils.hh +++ b/iod/tuple_utils.hh @@ -3,10 +3,10 @@ #include #include #include "utils.hh" + namespace iod { - constexpr int count_first_falses() { return 0; } template @@ -16,6 +16,49 @@ namespace iod else return 1 + count_first_falses(b...); } + + template + decltype(auto) arg_get_by_type_(std::enable_if_t>::value>*, + T1&& a1, T&&... args) + { + return std::forward(a1); + } + + + // template + // decltype(auto) arg_get_by_type_(std::enable_if_t>::value and std::is_same>::value>*, + // T1&& a1, T2&& a2, T&&... args) + // { + // return std::forward(a2); + // } + + template + decltype(auto) arg_get_by_type_(std::enable_if_t>::value>*, + T1&&, T&&... args) + { + return arg_get_by_type_(0, std::forward(args)...); + } + + template + decltype(auto) arg_get_by_type_(std::enable_if_t>::value and !std::is_same>::value>*, + T1&&, T2&&, T&&... args) + { + + return arg_get_by_type_(0, std::forward(args)...); + } + + template + decltype(auto) arg_get_by_type(T&&... args) + { + return arg_get_by_type_>(0, args...); + } + template decltype(auto) tuple_get_by_type(std::tuple& tuple) { diff --git a/iod/typelist.hh b/iod/typelist.hh new file mode 100644 index 0000000..4e64b3c --- /dev/null +++ b/iod/typelist.hh @@ -0,0 +1,58 @@ +#pragma once + +#include +#include "tuple_utils.hh" + +namespace iod +{ + + template + struct typelist {}; + + template + constexpr auto typelist_cat(typelist t1, typelist t2) + { + return typelist(); + } + + template + struct typelist_to_tuple {}; + + template + struct typelist_to_tuple> + { + typedef std::tuple type; + }; + + + template + struct tuple_to_typelist {}; + + template + struct tuple_to_typelist> + { + typedef typelist type; + }; + + template + using typelist_to_tuple_t = typename typelist_to_tuple::type; + template + using tuple_to_typelist_t = typename tuple_to_typelist::type; + + template + struct typelist_embeds : public std::false_type {}; + + template + struct typelist_embeds, U> : + public std::integral_constant::value...) != sizeof...(T)> + {}; + + + template + struct typelist_embeds_any_ref_of : public std::false_type {}; + + template + struct typelist_embeds_any_ref_of, U> : public typelist_embeds...>, std::decay_t> {}; + + +} From f6c3f863a05e7938adf97d510886e1afe512facb Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Thu, 17 Mar 2016 15:34:56 +0100 Subject: [PATCH 32/94] Remove iod cmake package. --- CMakeLists.txt | 23 ----------------------- tools/CMakeLists.txt | 1 - 2 files changed, 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ddda70..4620adc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,26 +10,3 @@ install(DIRECTORY iod DESTINATION include add_subdirectory(tools) add_subdirectory(tests) - -set(IOD_INCLUDE_DIR "include") -set(CMAKE_CONFIG_DEST "share/iod") - -include(CMakePackageConfigHelpers) -configure_package_config_file ( - ${CMAKE_SOURCE_DIR}/IodConfig.cmake.in - ${CMAKE_BINARY_DIR}/IodConfig.cmake - INSTALL_DESTINATION ${CMAKE_CONFIG_DEST} - PATH_VARS IOD_INCLUDE_DIR CMAKE_CONFIG_DEST) - -export(PACKAGE Iod) - -configure_file(IodConfigVersion.cmake.in - "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" @ONLY) - -install(FILES - "${PROJECT_BINARY_DIR}/IodConfig.cmake" - "${PROJECT_BINARY_DIR}/IodConfigVersion.cmake" - DESTINATION share/iod) - -# Install the export set for use with the install-tree -install(EXPORT IodTargets DESTINATION ${CMAKE_CONFIG_DEST}) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 7ff7dc0..c19d6e1 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -6,5 +6,4 @@ add_definitions(-std=c++14) add_executable(iod_generate_symbols iod_generate_symbols.cc) install(TARGETS iod_generate_symbols - EXPORT IodTargets DESTINATION bin) From 57221fefd67c24dd2d9e7e4c9da7f019a5c4eb12 Mon Sep 17 00:00:00 2001 From: Matthieu Garrigues Date: Wed, 18 May 2016 20:03:07 +0200 Subject: [PATCH 33/94] Fix compilation with the new GCC and CLANG compilers. --- iod/foreach.hh | 172 ++++++++++++++++++++++++++++++++------------- iod/sio_utils.hh | 2 +- iod/symbol.hh | 4 +- iod/tuple_utils.hh | 73 +++++++++++++++++++ tests/tuple.cc | 7 ++ 5 files changed, 207 insertions(+), 51 deletions(-) diff --git a/iod/foreach.hh b/iod/foreach.hh index 556be34..37140f8 100644 --- a/iod/foreach.hh +++ b/iod/foreach.hh @@ -16,45 +16,61 @@ namespace iod namespace internal { - template - inline - decltype(auto) - foreach_loop_tuple(std::enable_if_t*, F, A&&, R&&... results) + template + decltype(auto) tuple_foreach_i(F f, T&&... ts) { - return std::make_tuple(results...); + return f(std::get(ts)...); } - template - inline - decltype(auto) - foreach_loop_tuple(std::enable_if_t*, F f, A&& args_tuple, R&&... results) + template + inline void + tuple_foreach_impl(std::enable_if_t::value>*, + std::index_sequence si, + F f, T&&... ts) { - auto h = [] (auto&& a) -> decltype(auto) - { - return std::forward(a))>(std::get(a)); - }; - typedef decltype(h) H; - typedef decltype(proxy_apply(args_tuple, std::declval(), f)) return_type; - - return static_if::value>( - [&] (auto& args_tuple, auto& h, auto& f) - { - proxy_apply(args_tuple, h, f); - return foreach_loop_tuple(0, f, args_tuple, std::forward(results)...); - }, - [&] (auto& args_tuple, auto& h, auto& f) -> decltype(auto) - { - return foreach_loop_tuple - (0, f, args_tuple, std::forward(results)..., proxy_apply(args_tuple, h, f)); - }, args_tuple, h, f); + return (void)std::initializer_list{ + ((void)tuple_foreach_i(f, std::forward(ts)...), 0)...}; + } + template + inline decltype(auto) + tuple_foreach_impl(std::enable_if_t::value>*, + std::index_sequence si, + F f, T&&... ts) + { + return std::make_tuple(iod::internal::tuple_foreach_i(f, std::forward(ts)...)...); } + template + decltype(auto) sio_foreach_i(F f, T&&... ts) + { + return f(ts.template get_nth_member()...); + } + + template + inline void + sio_foreach_impl(std::enable_if_t::value>*, + std::index_sequence si, + F f, T&&... ts) + { + return (void)std::initializer_list{ + ((void)sio_foreach_i(f, std::forward(ts)...), 0)...}; + } + + template + inline decltype(auto) + sio_foreach_impl(std::enable_if_t::value>*, + std::index_sequence si, + F f, T&&... ts) + { + return D(iod::internal::sio_foreach_i(f, std::forward(ts)...)...); + } + template inline auto - foreach_loop_sio(std::enable_if_t*, F, A&&, R&&... results) + foreach2_loop_sio(std::enable_if_t*, F, A&&, R&&... results) { return static_if( [] () {}, @@ -64,7 +80,7 @@ namespace iod template inline auto - foreach_loop_sio(std::enable_if_t*, F f, A&& args_tuple, R&&... results) + foreach2_loop_sio(std::enable_if_t*, F f, A&& args_tuple, R&&... results) { auto h = [] (auto&& a) -> auto&& // avoid the lambda to convert references to values. { @@ -77,48 +93,105 @@ namespace iod [&] (auto& args_tuple) { proxy_apply(args_tuple, h, f); - return foreach_loop_sio(0, f, args_tuple, results...); + return foreach2_loop_sio(0, f, args_tuple, results...); }, [&] (auto& args_tuple) { - return foreach_loop_sio + return foreach2_loop_sio (0, f, args_tuple, results..., proxy_apply(args_tuple, h, f)); }, args_tuple); } + + template + inline void tuple_foreach(F f, std::tuple<> t1, T&&... ts) + { + } + + template + inline decltype(auto) tuple_foreach(F f, T1&& t1 , T&&... ts) + { + using seq = std::make_index_sequence>::value>; + using Ret = decltype(f(std::get<0>(t1), std::get<0>(ts)...)); + return iod::internal::tuple_foreach_impl(0, seq{}, + f, t1, std::forward(ts)...); + } + + template + inline void sio_foreach(std::enable_if_t::_size == 0>*, + F f, T1&& t1, T&&... ts) + { + } + template + inline decltype(auto) sio_foreach(std::enable_if_t::_size != 0>*, + F f, T1&& t1 , T&&... ts) + { + const size_t size = std::remove_reference_t::_size; + using seq = std::make_index_sequence; + using Ret = decltype(f(t1.template get_nth_member<0>(), ts.template get_nth_member<0>()...)); + return iod::internal::sio_foreach_impl(0, seq{}, + f, t1, std::forward(ts)...); + } template struct foreach_tuple_caller { foreach_tuple_caller(T&& t) : t_(t) {} + template + decltype(auto) run(F f, std::index_sequence) + { + return iod::internal::tuple_foreach(f, std::get(t_)...); + } + template - auto operator|(F f) + decltype(auto) operator|(F f) { - const int size = std::tuple_size(t_))>>::value; - return internal::foreach_loop_tuple<0, size>(0, f, t_); + return run(f, std::make_index_sequence::value>{}); } const T t_; }; + template struct foreach_sio_caller { foreach_sio_caller(T&& t) : t_(t) {} + + template + decltype(auto) run(F f, std::index_sequence) + { + return iod::internal::sio_foreach(0, f, std::get(t_)...); + } + + template + decltype(auto) operator|(F f) + { + return run(f, std::make_index_sequence::value>{}); + } + + const T t_; + }; + + template + struct foreach2_sio_caller + { + foreach2_sio_caller(T&& t) : t_(t) {} + template auto operator|(F f) { const int size = std::remove_reference_t(t_))>::_size; - return internal::foreach_loop_sio<0, size>(0, f, t_); + return internal::foreach2_loop_sio<0, size>(0, f, t_); } const T t_; }; - + } template @@ -150,6 +223,21 @@ namespace iod } + template + auto foreach2(sio& a1, T&&... args) + { + return internal::foreach2_sio_caller + (std::forward_as_tuple(a1, args...)); + } + + template + auto foreach2(const sio& a1, T&&... args) + { + return internal::foreach2_sio_caller + (std::forward_as_tuple(a1, args...)); + } + + namespace internal { @@ -230,18 +318,6 @@ namespace iod (std::forward_as_tuple(a1, args...), prev_init); } - // template - // auto foreach(F f, sio& a1, T&&... args) - // { - // return internal::foreach_loop_sio<0, sizeof...(S)>(0, f, std::forward_as_tuple(a1, args...)); - // } - - // template - // auto foreach(F f, const sio& a1, T&&... args) - // { - // return internal::foreach_loop_sio<0, sizeof...(S)>(0, f, std::forward_as_tuple(a1, args...)); - // } - template inline auto diff --git a/iod/sio_utils.hh b/iod/sio_utils.hh index 8c2d81f..4613c77 100644 --- a/iod/sio_utils.hh +++ b/iod/sio_utils.hh @@ -141,7 +141,7 @@ namespace iod inline auto intersect(const sio& a, const sio& b) { - return foreach(a) | [] (auto& m) { + return foreach2(a) | [] (auto& m) { return static_if, std::decay_t>::value>( [&] () { return m; }, [&] () { }); diff --git a/iod/symbol.hh b/iod/symbol.hh index 63254cc..b04d554 100644 --- a/iod/symbol.hh +++ b/iod/symbol.hh @@ -48,9 +48,9 @@ namespace iod typedef NAME##_t symbol_type; \ typedef iod::variable> super; \ \ - variable_type() {} \ + variable_type() = default; \ template \ - variable_type(V v) : SYMBOL(v) {} \ + variable_type(V v, std::enable_if_t::value>* = 0) : SYMBOL(v) {} \ inline value_type& value() { return SYMBOL; } \ inline const value_type& value() const { return SYMBOL; } \ auto symbol() const { return NAME##_t(); } \ diff --git a/iod/tuple_utils.hh b/iod/tuple_utils.hh index b9d0ccf..3f4151e 100644 --- a/iod/tuple_utils.hh +++ b/iod/tuple_utils.hh @@ -155,5 +155,78 @@ namespace iod template using tuple_remove_elements_t = typename tuple_remove_elements::type; + + + template + inline F tuple_map(std::tuple& t, F f, std::index_sequence) + { + return (void)std::initializer_list{((void)f(std::get(t)), 0)...}, f; + } + + template + inline void tuple_map(std::tuple& t, F f) + { + tuple_map(t, f, std::index_sequence_for{}); + } + + template + inline decltype(auto) tuple_transform(T&& t, F f, std::index_sequence) + { + return std::make_tuple(f(std::get(std::forward(t)))...); + } + + template + inline decltype(auto) tuple_transform(T&& t, F f) + { + return tuple_transform(std::forward(t), f, + std::make_index_sequence>{}>{}); + } + + template