#ifndef EOLIAN_CXX_SEQUENCE_HH #define EOLIAN_CXX_SEQUENCE_HH #include "grammar/generator.hpp" namespace efl { namespace eolian { namespace grammar { template struct sequence_generator; template struct sequence_size : std::integral_constant {}; template struct sequence_size> : std::integral_constant::value> {}; template bool generate_sequence(L const& l, R const& r , OutputIterator sink, Attribute const& attr, Context const& context , typename std::enable_if::value>::type* = 0) { auto gen_left = as_generator(l); bool b = attributes::generate(gen_left, sink, attr, context); if(b) { return attributes::generate(as_generator(r), sink , attributes::pop_front_n::value> (attr), context); } else return false; } template bool generate_sequence(L const& l, R const& r , OutputIterator sink, Attribute const& attr, Context const& context , typename std::enable_if < !type_traits::is_tuple::value && type_traits::attributes_needed::value == 0 && type_traits::attributes_needed::value == 1 >::type* = 0) { bool b = as_generator(l).generate(sink, attributes::unused, context); if(b) { return as_generator(r).generate(sink, attr, context); } else return false; } template bool generate_sequence(L const& l, R const& r , OutputIterator sink, Attribute const&, Context const& context , typename std::enable_if < !type_traits::is_tuple::value && type_traits::attributes_needed::value == 0 && type_traits::attributes_needed::value == 0 >::type* = 0) { bool b = as_generator(l).generate(sink, attributes::unused, context); if(b) { return as_generator(r).generate(sink, attributes::unused, context); } else return false; } template bool generate_sequence(L const& l, R const& r , OutputIterator sink, Attribute const& attr, Context const& context , typename std::enable_if < !type_traits::is_tuple::value && type_traits::attributes_needed::value == 1 && type_traits::attributes_needed::value == 0 >::type* = 0) { bool b = as_generator(l).generate(sink, attr, context); if(b) { return as_generator(r).generate(sink, attributes::unused, context); } else return false; } template bool generate_sequence(L const& l, R const& r, OutputIterator sink, attributes::unused_type, Context const& context) { bool b = as_generator(l).generate(sink, attributes::unused, context); if(b) { return as_generator(r).generate(sink, attributes::unused, context); } else return false; } template struct sequence_generator { template bool generate(OutputIterator sink, Attribute const& attribute, Context const& context) const { return grammar::generate_sequence(left, right, sink, attribute, context); } L left; R right; }; template struct is_eager_generator > : std::true_type {}; template struct is_generator > : std::true_type {}; namespace type_traits { template struct attributes_needed > : std::integral_constant ::value + attributes_needed::value> {}; template struct accepts_tuple > : std::true_type {}; } template typename std::enable_if::value && grammar::is_generator::value, sequence_generator>::type operator<<(L l, R r) { return sequence_generator{l, r}; } } } } #endif