From b9133cf3a1a55ef959904bbb1f4dc50c337af45a Mon Sep 17 00:00:00 2001 From: rbock Date: Tue, 6 May 2014 22:41:19 +0200 Subject: [PATCH] Used index_sequence to get rid of recursion in interpret_tuple. Wonderful stuff, shaped after code samples from cppreference and stackoverflow. --- include/sqlpp11/vendor/interpret_tuple.h | 57 +++++++++++------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/include/sqlpp11/vendor/interpret_tuple.h b/include/sqlpp11/vendor/interpret_tuple.h index 9c067627..1f75129b 100644 --- a/include/sqlpp11/vendor/interpret_tuple.h +++ b/include/sqlpp11/vendor/interpret_tuple.h @@ -30,47 +30,40 @@ #include #include #include +#include namespace sqlpp { - template - struct tuple_interpreter_t + template + static void interpret_tuple_element(const Element& element, const Separator& separator, Context& context, size_t index) { - template - static void _(const Tuple& t, const Separator& separator, Context& context) - { - _impl(t, separator, context, type<0>()); - }; + if (index) + context << separator; + if (requires_braces_t::value) + context << "("; + serialize(element, context); + if (requires_braces_t::value) + context << ")"; + } - private: - template struct type {}; - - template - static void _impl(const Tuple& t, const Separator& separator, Context& context, const type&) - { - if (index) - context << separator; - const auto& entry = std::get(t); - using entry_type = typename std::tuple_element::type; - if (requires_braces_t::value) - context << "("; - serialize(entry, context); - if (requires_braces_t::value) - context << ")"; - _impl(t, separator, context, type()); - } - - template - static void _impl(const Tuple& t, const Separator& separator, Context& context, const type::value>&) - { - } - }; + template + auto interpret_tuple_impl(const Tuple& t, const Separator& separator, Context& context, const ::sqlpp::detail::index_sequence&) + -> Context& + { + // Note: A braced-init-list does guarantee the order of evaluation according to 12.6.1 [class.explicit.init] paragraph 2 and 8.5.4 [dcl.init.list] paragraph 4. + // See for example: "http://en.cppreference.com/w/cpp/utility/integer_sequence" + // See also: "http://stackoverflow.com/questions/6245735/pretty-print-stdtuple/6245777#6245777" + // Beware of gcc-bug: "http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253", otherwise an empty swallow struct could be used + using swallow = int[]; + (void) swallow{(interpret_tuple_element(std::get(t), separator, context, Is) ,0)...}; + return context; + } template auto interpret_tuple(const Tuple& t, const Separator& separator, Context& context) - -> decltype(tuple_interpreter_t::_(t, separator, context)) + -> Context& { - return tuple_interpreter_t::_(t, separator, context); + return interpret_tuple_impl(t, separator, context, ::sqlpp::detail::make_index_sequence::value>{}); } }