Commit 604dd27a authored by Bednárek David RNDr. Ph.D.'s avatar Bednárek David RNDr. Ph.D.
Browse files

reflexion code generator almost working

parent e81cfbf4
......@@ -40,10 +40,24 @@ namespace fmwkng {
enum class element_sense { OPEN, CLOSE };
template< element_sense sense>
struct sense_traits;
template<>
struct sense_traits< element_sense::OPEN> {
static auto code_name() { return "fmwkng::impl::element_sense::OPEN"; }
};
template<>
struct sense_traits< element_sense::CLOSE> {
static auto code_name() { return "fmwkng::impl::element_sense::CLOSE"; }
};
class abstract_element : immovable {
public:
virtual ~abstract_element() noexcept = default;
virtual element_ptr clone() const = 0;
virtual void make_code(std::ostream& os) const = 0;
virtual std::size_t data_size() const = 0;
virtual void data_text(std::ostream& os, std::size_t i) const = 0;
virtual void metadata_marker(std::ostream& os) const = 0;
......@@ -254,6 +268,15 @@ namespace fmwkng {
return el;
}
template< typename tag>
struct tag_traits
{
static void code_tag(std::ostream& os)
{
os << tag::code_name();
}
};
template< typename tag_category, typename tag, element_sense sense>
struct element_traits;
......@@ -458,6 +481,68 @@ namespace fmwkng {
}
}
void print_node_code(const reducer_node& rn, std::size_t depth,
const element_observer_vector& openers = {},
const element_observer_vector& closers = {})
{
if (depth != 0)
{
if (!(*rn.source_range.begin())->reducible())
{
auto o2 = openers;
auto c2 = closers;
o2.push_back(&**rn.source_range.begin());
c2.push_back(&**(rn.source_range.end() - 1));
for (auto&& a : rn.children)
{
print_node_code(a, depth - 1, o2, c2);
}
}
}
else
{
std::cout << "{";
std::cout << std::endl;
std::cout << " {";
std::cout << std::endl;
for (auto&& a : openers)
{
std::cout << " ";
a->make_code(std::cout);
std::cout << ",";
std::cout << std::endl;
}
for (auto&& a : rn.reduced_children)
{
if (a->sense() == element_sense::OPEN)
{
std::cout << " ";
a->make_code(std::cout);
std::cout << ",";
std::cout << std::endl;
}
}
std::cout << " },";
std::cout << std::endl;
std::cout << " {";
std::cout << std::endl;
for (auto&& a : rn.reduced_children)
{
if (a->sense() == element_sense::CLOSE)
{
std::cout << " ";
a->make_code(std::cout);
std::cout << ",";
std::cout << std::endl;
}
}
std::cout << " }";
std::cout << std::endl;
std::cout << "}";
std::cout << std::endl;
}
}
reducer_list reduce_list(element_list_view el)
{
auto b = el.begin();
......@@ -497,6 +582,7 @@ namespace fmwkng {
for (auto&& a : root)
{
print_node(a, d, openers);
print_node_code(a, d, openers);
}
}
}
......@@ -507,40 +593,48 @@ namespace fmwkng {
explicit element(data_t d)
: d_(std::move(d))
{}
element_ptr clone() const
virtual element_ptr clone() const override
{
return std::make_unique< self_>(d_);
}
virtual std::size_t data_size() const
virtual void make_code(std::ostream& os) const override
{
os << "std::make_unique<element_t<";
tag_traits<tag>::code_tag(os);
os << "," << sense_traits<sense_p>::code_name() << ">>(";
my_traits::code_data(os, d_);
os << ")";
}
virtual std::size_t data_size() const override
{
return 1;
}
virtual void data_text(std::ostream& os, std::size_t i) const
virtual void data_text(std::ostream& os, std::size_t i) const override
{
assert(i == 0);
my_traits::data_text(os, d_);
}
virtual void metadata_marker(std::ostream& os) const
virtual void metadata_marker(std::ostream& os) const override
{
my_traits::metadata_marker(os);
}
virtual element_sense sense() const
virtual element_sense sense() const override
{
return sense_p;
}
virtual bool useful() const
virtual bool useful() const override
{
return my_traits::useful;
}
virtual bool reducible() const
virtual bool reducible() const override
{
return my_traits::reducible;
}
virtual element_ptr aggregate_init() const
virtual element_ptr aggregate_init() const override
{
return std::make_unique< my_aggregate>(my_traits::aggregator_data(d_));
}
virtual void aggregate_to(abstract_element* aggr) const
virtual void aggregate_to(abstract_element* aggr) const override
{
auto p = dynamic_cast<my_aggregate*>(aggr);
assert(!!p);
......@@ -562,39 +656,45 @@ namespace fmwkng {
public:
element()
{}
element_ptr clone() const
virtual element_ptr clone() const override
{
return std::make_unique< self_>();
}
virtual std::size_t data_size() const
virtual void make_code(std::ostream& os) const override
{
os << "std::make_unique<element_t<";
tag_traits<tag>::code_tag(os);
os << "," << sense_traits<sense_p>::code_name() << ">>()";
}
virtual std::size_t data_size() const override
{
return 0;
}
virtual void data_text(std::ostream& os, std::size_t i) const
virtual void data_text(std::ostream& os, std::size_t i) const override
{
assert(false);
}
virtual void metadata_marker(std::ostream& os) const
virtual void metadata_marker(std::ostream& os) const override
{
my_traits::metadata_marker(os);
}
virtual element_sense sense() const
virtual element_sense sense() const override
{
return sense_p;
}
virtual bool useful() const
virtual bool useful() const override
{
return false;
}
virtual bool reducible() const
virtual bool reducible() const override
{
return my_traits::reducible;
}
virtual element_ptr aggregate_init() const
virtual element_ptr aggregate_init() const override
{
return std::make_unique< my_aggregate>();
}
virtual void aggregate_to(abstract_element* aggr) const
virtual void aggregate_to(abstract_element* aggr) const override
{
assert(!!dynamic_cast<my_aggregate*>(aggr));
}
......@@ -635,40 +735,48 @@ namespace fmwkng {
explicit config_element(data_t d)
: d_(std::move(d))
{}
virtual element_ptr clone() const
virtual element_ptr clone() const override
{
return std::make_unique< self_>(d_);
}
virtual std::size_t data_size() const
virtual void make_code(std::ostream& os) const override
{
os << "std::make_unique<config_element<";
tag_traits<tag>::code_tag(os);
os << ",element_sense::OPEN>>(";
my_traits::code_data(os, d_);
os << ")";
}
virtual std::size_t data_size() const override
{
return 1;
}
virtual void data_text(std::ostream& os, std::size_t i) const
virtual void data_text(std::ostream& os, std::size_t i) const override
{
assert(i == 0);
my_traits::data_text(os, d_);
}
virtual void metadata_marker(std::ostream& os) const
virtual void metadata_marker(std::ostream& os) const override
{
my_traits::metadata_marker_open(os);
}
virtual element_sense sense() const
virtual element_sense sense() const override
{
return element_sense::OPEN;
}
virtual bool useful() const
virtual bool useful() const override
{
return false;
}
virtual bool reducible() const
virtual bool reducible() const override
{
return false;
}
virtual element_ptr aggregate_init() const
virtual element_ptr aggregate_init() const override
{
return std::make_unique< my_aggregate>(my_traits::aggregator_data(d_));
}
virtual void aggregate_to(abstract_element* aggr) const
virtual void aggregate_to(abstract_element* aggr) const override
{
auto p = dynamic_cast<my_aggregate*>(aggr);
assert(!!p);
......@@ -687,43 +795,49 @@ namespace fmwkng {
template< typename tag>
class config_element< tag, element_sense::CLOSE> : public abstract_element {
private:
using my_element_traits = element_traits_t<tag, element_sense::OPEN>;
using my_element_traits = element_traits_t<tag, element_sense::CLOSE>;
public:
config_element()
{}
element_ptr clone() const
virtual element_ptr clone() const override
{
return std::make_unique< self_>();
}
virtual std::size_t data_size() const
virtual void make_code(std::ostream& os) const override
{
os << "std::make_unique<config_element<";
tag_traits<tag>::code_tag(os);
os << ",element_sense::CLOSE>>()";
}
virtual std::size_t data_size() const override
{
return 0;
}
virtual void data_text(std::ostream& os, std::size_t i) const
virtual void data_text(std::ostream& os, std::size_t i) const override
{
assert(false);
}
virtual void metadata_marker(std::ostream& os) const
virtual void metadata_marker(std::ostream& os) const override
{
my_traits::metadata_marker_close(os);
}
virtual element_sense sense() const
virtual element_sense sense() const override
{
return element_sense::CLOSE;
}
virtual bool useful() const
virtual bool useful() const override
{
return false;
}
virtual bool reducible() const
virtual bool reducible() const override
{
return false;
}
virtual element_ptr aggregate_init() const
virtual element_ptr aggregate_init() const override
{
return std::make_unique< my_aggregate>();
}
virtual void aggregate_to(abstract_element* aggr) const
virtual void aggregate_to(abstract_element* aggr) const override
{
assert(!!dynamic_cast<my_aggregate*>(aggr));
}
......@@ -740,39 +854,45 @@ namespace fmwkng {
public:
result_element()
{}
element_ptr clone() const
virtual element_ptr clone() const override
{
return std::make_unique< self_>();
}
virtual std::size_t data_size() const
virtual void make_code(std::ostream& os) const override
{
os << "std::make_unique<result_element<";
tag_traits<tag>::code_tag(os);
os << ",element_sense::OPEN>>()";
}
virtual std::size_t data_size() const override
{
return 0;
}
virtual void data_text(std::ostream& os, std::size_t i) const
virtual void data_text(std::ostream& os, std::size_t i) const override
{
assert(false);
}
virtual void metadata_marker(std::ostream& os) const
virtual void metadata_marker(std::ostream& os) const override
{
my_traits::metadata_marker_open(os);
}
virtual element_sense sense() const
virtual element_sense sense() const override
{
return element_sense::OPEN;
}
virtual bool useful() const
virtual bool useful() const override
{
return false;
}
virtual bool reducible() const
virtual bool reducible() const override
{
return false;
}
virtual element_ptr aggregate_init() const
virtual element_ptr aggregate_init() const override
{
return std::make_unique< my_aggregate>();
}
virtual void aggregate_to(abstract_element* aggr) const
virtual void aggregate_to(abstract_element* aggr) const override
{
assert(!!dynamic_cast<my_aggregate*>(aggr));
}
......@@ -792,40 +912,48 @@ namespace fmwkng {
explicit result_element(data_t d)
: d_(std::move(d))
{}
virtual element_ptr clone() const
virtual element_ptr clone() const override
{
return std::make_unique< self_>(d_);
}
virtual std::size_t data_size() const
virtual void make_code(std::ostream& os) const override
{
os << "std::make_unique<result_element<";
tag_traits<tag>::code_tag(os);
os << ",element_sense::CLOSE>>(";
my_traits::code_data(os, d_);
os << ")";
}
virtual std::size_t data_size() const override
{
return 1;
}
virtual void data_text(std::ostream& os, std::size_t i) const
virtual void data_text(std::ostream& os, std::size_t i) const override
{
assert(i == 0);
my_traits::data_text(os, d_);
}
virtual void metadata_marker(std::ostream& os) const
virtual void metadata_marker(std::ostream& os) const override
{
my_traits::metadata_marker_close(os);
}
virtual element_sense sense() const
virtual element_sense sense() const override
{
return element_sense::CLOSE;
}
virtual bool useful() const
virtual bool useful() const override
{
return false;
}
virtual bool reducible() const
virtual bool reducible() const override
{
return false;
}
virtual element_ptr aggregate_init() const
virtual element_ptr aggregate_init() const override
{
return std::make_unique< my_aggregate>(my_traits::aggregator_data(d_));
}
virtual void aggregate_to(abstract_element* aggr) const
virtual void aggregate_to(abstract_element* aggr) const override
{
auto p = dynamic_cast<my_aggregate*>(aggr);
assert(!!p);
......@@ -1359,9 +1487,31 @@ namespace fmwkng {
using tag_category = platform_tag_category;
};
namespace impl {
template<>
struct tag_traits<all_platforms_tag>
{
static void code_tag(std::ostream& os)
{
os << "fmwkng::all_platforms_tag";
}
};
}
struct all_threads_tag {
using tag_category = parallel_tag_category;
};
namespace impl {
template<>
struct tag_traits<all_threads_tag>
{
static void code_tag(std::ostream& os)
{
os << "fmwkng::all_threads_tag";
}
};
}
#pragma endregion
namespace impl {
#pragma region utils2
......@@ -1381,6 +1531,15 @@ namespace fmwkng {
using config_type = config_t;
};
template< typename config_t>
struct tag_traits<root_tag<config_t>>
{
static void code_tag(std::ostream& os)
{
os << "fmwkng::impl::root_tag<" << config_t::code_name() << ">";
}
};
template< typename config_t>
struct element_traits< root_tag_category, root_tag< config_t>, element_sense::OPEN>
{
......@@ -1672,6 +1831,10 @@ namespace fmwkng {
{
os << platform_tag::name();
}
static void code_data(std::ostream& os, const data_type&)
{
os << "std::monostate{}";
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
template< element_sense sense>
......@@ -1753,6 +1916,14 @@ namespace fmwkng {
{
os << d.first;
}
static void code_data(std::ostream& os, const data_type& d)
{
os << "std::make_pair("
<< d.first
<< ",";
d.second.code_data(os);
os << ")";
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
template< element_sense sense>
......@@ -1797,6 +1968,10 @@ namespace fmwkng {
{
os << "all";
}
static void code_data(std::ostream& os, const data_type& d)
{
os << "std::monostate()";
}
template< element_sense sense>
using aggregator = config_element< all_platforms_tag, sense>;
static data_type aggregator_data(const data_type&)
......@@ -1825,6 +2000,10 @@ namespace fmwkng {
{
os << "all";
}
static void code_data(std::ostream& os, const data_type& d)
{
os << "std::monostate()";
}
template< element_sense sense>
using aggregator = config_element< all_threads_tag, sense>;
static data_type aggregator_data(const data_type&)
......@@ -1853,6 +2032,10 @@ namespace fmwkng {
{
d.data_text(os);
}
static void code_data(std::ostream& os, const data_type& d)
{
d.code_data(os);
}
template< element_sense sense>
using aggregator = config_element< range_tag, sense>;
static data_type aggregator_data(const data_type& v)
......@@ -1947,6 +2130,15 @@ namespace fmwkng {
using tag_category = parallel_tag_category;
};
template<>
struct tag_traits<parallel_tag>
{
static void code_tag(std::ostream& os)
{
os << "fmwkng::impl::parallel_tag";
}
};
template<>
struct element_traits< parallel_tag_category, parallel_tag, element_sense::OPEN>
{
......@@ -1959,6 +2151,10 @@ namespace fmwkng {
{
os << d;
}
static void code_data(std::ostream& os, const data_type& d)
{
os << d;
}
static constexpr bool useful = false;
static constexpr bool reducible = false;
template< element_sense sense>
......@@ -2138,6 +2334,15 @@ namespace fmwkng {
using tag_category = measurement_tag_category;
};
template<>
struct tag_traits<measurement_tag>
{
static void code_tag(std::ostream& os)
{
os << "fmwkng::impl::measurement_tag";
}
};
using clock = std::chrono::high_resolution_clock;
template<>
......@@ -2165,6 +2370,12 @@ namespace fmwkng {
{
os << d.count();
}
static void code_data(std::ostream& os, const data_type& d)
{
os << "std::clock::duration("
<< d.count()
<< ")";
}
static constexpr bool useful = true;
static constexpr bool reducible = true;
using aggregator_data_type = std::pair< clock::duration, std::size_t>;
......@@ -2198,6 +2409,13 @@ namespace fmwkng {
{
os << (d.first.count() / d.second);
}
static void code_data(std::ostream& os, const data_type& d)
{
os << "std::make_pair(clock::duration("
<< d.first.count()
<< ")," << d.second
<< ")";
}
template< element_sense sense>
using aggregator = result_element< measurement_tag, sense>;
static data_type aggregator_data(const data_type& v)
......@@ -2281,6 +2499,10 @@ namespace fmwkng {