#ifndef EOLIAN_CXX_ATTRIBUTES_HH #define EOLIAN_CXX_ATTRIBUTES_HH #include #include #include "grammar/type_traits.hpp" namespace efl { namespace eolian { namespace grammar { namespace attributes { struct unused_type {}; unused_type const unused = {}; template struct tuple_element; template struct tuple_element::value>::type> : std::tuple_element {}; template typename tuple_element::type>::type get_adl(Tuple& tuple) { using std::get; return get(tuple); } template struct lazy_offset_tuple { lazy_offset_tuple(Tuple& tuple) : tuple(tuple) {} template typename tuple_element::type>::type get() const { return attributes::get_adl(tuple); } Tuple& tuple; }; } namespace type_traits { template struct is_tuple> : std::true_type {}; template struct is_explicit_tuple> : std::true_type {}; } namespace attributes { template struct infinite_tuple { T object; }; template infinite_tuple make_infinite_tuple(T&& object) { return infinite_tuple{std::forward(object)}; } template struct tuple_element> { typedef T type; static type& get(infinite_tuple& tuple) { return tuple.object; } static type const& get(infinite_tuple const& tuple) { return tuple.object; } }; template struct tuple_element const> : tuple_element> {}; template typename tuple_element>::type& get(infinite_tuple& tuple) { return tuple_element>::get(tuple); } template typename tuple_element>::type const& get(infinite_tuple const& tuple) { return tuple_element>::get(tuple); } } namespace type_traits { template struct is_tuple> : std::true_type {}; template struct is_explicit_tuple> : std::true_type {}; } namespace attributes { template struct tuple_element> : tuple_element::type> {}; template struct tuple_element const> : tuple_element::type> {}; template typename tuple_element const>::type get(lazy_offset_tuple const& tuple) { return tuple.template get(); } template lazy_offset_tuple<1, Tuple> pop_front(Tuple& tuple, typename std::enable_if::value>::type* = 0) { return lazy_offset_tuple<1, Tuple>(tuple); } template lazy_offset_tuple pop_front(lazy_offset_tuple tuple, typename std::enable_if::value>::type* = 0) { return lazy_offset_tuple(tuple.tuple); } template lazy_offset_tuple pop_front_n(Tuple& tuple, typename std::enable_if::value && I>::type* = 0) { return lazy_offset_tuple(tuple); } template Tuple& pop_front_n(Tuple& tuple, typename std::enable_if::type* = 0) { return tuple; } template lazy_offset_tuple pop_front_n(lazy_offset_tuple tuple, typename std::enable_if::value>::type* = 0) { return lazy_offset_tuple(tuple.tuple); } template bool generate(Generator const& gen, OutputIterator sink, Attribute const& attribute, Context const& context , typename std::enable_if ::value && !type_traits::accepts_tuple::value && type_traits::attributes_needed::value != 0 >::type* = 0) { return gen.generate(sink, get<0>(attribute), context); } template bool generate(Generator const& gen, OutputIterator sink, Attribute const& attribute, Context const& context , typename std::enable_if ::value && type_traits::accepts_tuple::value && type_traits::attributes_needed::value != 0 >::type* = 0) { return gen.generate(sink, attribute, context); } template bool generate(Generator const& gen, OutputIterator sink, Attribute const& , Context const& context , typename std::enable_if ::value == 0 >::type* = 0) { return gen.generate(sink, unused, context); } template bool generate(Generator const& gen, OutputIterator sink, Attribute const& attribute, Context const& context , typename std::enable_if ::value && type_traits::attributes_needed::value != 0 >::type* = 0) { return gen.generate(sink, attribute, context); } } } } } #endif