From db0ef64c04933c854f6d87d37e728b7ebfb8e082 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 3 Jul 2014 11:29:04 -0700 Subject: [PATCH] feat(util/lazy_list_fn): handle the 'is_nil' case more efficiently Signed-off-by: Leonardo de Moura --- src/util/lazy_list_fn.h | 136 +++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 57 deletions(-) diff --git a/src/util/lazy_list_fn.h b/src/util/lazy_list_fn.h index 758666c07..a092886c8 100644 --- a/src/util/lazy_list_fn.h +++ b/src/util/lazy_list_fn.h @@ -30,7 +30,7 @@ void for_each(lazy_list l, F && f) { */ template lazy_list take(unsigned sz, lazy_list const & l) { - if (sz == 0) { + if (sz == 0 || l.is_nil()) { return lazy_list(); } else { return mk_lazy_list([=]() { @@ -62,15 +62,20 @@ lazy_list to_lazy(list l) { */ template lazy_list append(lazy_list const & l1, lazy_list const & l2, char const * cname = "lazy list") { - return mk_lazy_list([=]() { - auto p = l1.pull(); - if (!p) { - check_system(cname); - return l2.pull(); - } else { - return some(mk_pair(p->first, append(p->second, l2, cname))); - } - }); + if (l1.is_nil()) + return l2; + else if (l2.is_nil()) + return l1; + else + return mk_lazy_list([=]() { + auto p = l1.pull(); + if (!p) { + check_system(cname); + return l2.pull(); + } else { + return some(mk_pair(p->first, append(p->second, l2, cname))); + } + }); } /** @@ -78,15 +83,18 @@ lazy_list append(lazy_list const & l1, lazy_list const & l2, char const */ template lazy_list orelse(lazy_list const & l1, lazy_list const & l2, char const * cname = "lazy list") { - return mk_lazy_list([=]() { - auto p = l1.pull(); - if (!p) { - check_system(cname); - return l2.pull(); - } else { - return p; - } - }); + if (l1.is_nil()) + return l2; + else + return mk_lazy_list([=]() { + auto p = l1.pull(); + if (!p) { + check_system(cname); + return l2.pull(); + } else { + return p; + } + }); } /** @@ -95,15 +103,20 @@ lazy_list orelse(lazy_list const & l1, lazy_list const & l2, char const */ template lazy_list interleave(lazy_list const & l1, lazy_list const & l2, char const * cname = "lazy list") { - return mk_lazy_list([=]() { - auto p = l1.pull(); - if (!p) { - check_system(cname); - return l2.pull(); - } else { - return some(mk_pair(p->first, interleave(l2, p->second, cname))); - } - }); + if (l1.is_nil()) + return l2; + else if (l2.is_nil()) + return l1; + else + return mk_lazy_list([=]() { + auto p = l1.pull(); + if (!p) { + check_system(cname); + return l2.pull(); + } else { + return some(mk_pair(p->first, interleave(l2, p->second, cname))); + } + }); } /** @@ -111,15 +124,18 @@ lazy_list interleave(lazy_list const & l1, lazy_list const & l2, char c */ template lazy_list map(lazy_list const & l, F && f, char const * cname = "lazy list") { - return mk_lazy_list([=]() { - auto p = l.pull(); - if (!p) { - return p; - } else { - check_system(cname); - return some(mk_pair(f(p->first), map(p->second, f, cname))); - } - }); + if (l.is_nil()) + return l; + else + return mk_lazy_list([=]() { + auto p = l.pull(); + if (!p) { + return p; + } else { + check_system(cname); + return some(mk_pair(f(p->first), map(p->second, f, cname))); + } + }); } /** @@ -127,15 +143,18 @@ lazy_list map(lazy_list const & l, F && f, char const * cname = "lazy list */ template lazy_list map2(lazy_list const & l, F && f, char const * cname = "lazy list") { - return mk_lazy_list([=]() { - typename lazy_list::maybe_pair p = l.pull(); - if (!p) { - return typename lazy_list::maybe_pair(); - } else { - check_system(cname); - return some(mk_pair(f(p->first), map2(p->second, f, cname))); - } - }); + if (l.is_nil()) + return lazy_list(); + else + return mk_lazy_list([=]() { + typename lazy_list::maybe_pair p = l.pull(); + if (!p) { + return typename lazy_list::maybe_pair(); + } else { + check_system(cname); + return some(mk_pair(f(p->first), map2(p->second, f, cname))); + } + }); } /** @@ -147,17 +166,20 @@ lazy_list map2(lazy_list const & l, F && f, char const * cname = "lazy */ template lazy_list filter(lazy_list const & l, P && pred, char const * cname = "lazy list") { - return mk_lazy_list([=]() { - auto p = l.pull(); - if (!p) { - return p; - } else if (pred(p->first)) { - return p; - } else { - check_system(cname); - return filter(p->second, pred, cname).pull(); - } - }); + if (l.is_nil()) + return l; + else + return mk_lazy_list([=]() { + auto p = l.pull(); + if (!p) { + return p; + } else if (pred(p->first)) { + return p; + } else { + check_system(cname); + return filter(p->second, pred, cname).pull(); + } + }); } /**