[cfe-commits] [libcxx] r108151 - in /libcxx/trunk: include/regex test/re/re.alg/re.alg.search/basic.pass.cpp

Howard Hinnant hhinnant at apple.com
Mon Jul 12 08:51:17 PDT 2010


Author: hhinnant
Date: Mon Jul 12 10:51:17 2010
New Revision: 108151

URL: http://llvm.org/viewvc/llvm-project?rev=108151&view=rev
Log:
Redesign number 3.  The previous design was not handling matching of empty strings inside of loops.

Modified:
    libcxx/trunk/include/regex
    libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp

Modified: libcxx/trunk/include/regex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/regex?rev=108151&r1=108150&r2=108151&view=diff
==============================================================================
--- libcxx/trunk/include/regex (original)
+++ libcxx/trunk/include/regex Mon Jul 12 10:51:17 2010
@@ -717,6 +717,7 @@
 } // std
 */
 
+// temporary!
 #include <sstream>
 #include <cassert>
 
@@ -729,7 +730,7 @@
 #include <string>
 #include <memory>
 #include <vector>
-#include <__split_buffer>
+#include <deque>
 
 #pragma GCC system_header
 
@@ -1218,10 +1219,12 @@
     return __value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
 }
 
-template <class _CharT> class __state;
+template <class _CharT> class __node;
+
+template <class _BidirectionalIterator> class sub_match;
 
 template <class _CharT>
-struct __command
+struct __state
 {
     enum
     {
@@ -1233,107 +1236,93 @@
         __accept_and_consume,  // -995
         __accept_but_not_consume,  // -994
         __reject,                  // -993
-        __zero_loop_count,
-        __increment_loop_count,
-        __zero_marked_exprs,
+        __split,
+        __repeat
     };
 
-    typedef _STD::__state<_CharT> __state;
-
     int __do_;
-    const __state* first;
-    const __state* second;
-
-    __command() : __do_(__reject), first(nullptr), second(nullptr) {}
-    explicit __command(int __do)
-        : __do_(__do), first(nullptr), second(nullptr) {}
-    __command(int __do, const __state* __s1, const __state* __s2 = nullptr)
-        : __do_(__do), first(__s1), second(__s2) {}
-    explicit __command(const __state* __s1, const __state* __s2 = nullptr)
-        : __do_(0), first(__s1), second(__s2) {}
+    const _CharT* __first_;
+    const _CharT* __current_;
+    const _CharT* __last_;
+    vector<sub_match<const _CharT*> > __sub_matches_;
+    vector<pair<size_t, const _CharT*> > __loop_data_;
+    const __node<_CharT>* __node_;
+    regex_constants::match_flag_type __flags_;
+
+    __state()
+        : __do_(0), __first_(nullptr), __current_(nullptr), __last_(nullptr),
+          __node_(nullptr), __flags_() {}
 };
 
 template <class _CharT>
 ostream&
-operator<<(ostream& os, const __command<_CharT>& c)
+operator<<(ostream& os, const __state<_CharT>& c)
 {
     os << c.__do_;
-    if (c.first)
-        os << ", " << c.first->speak();
-    if (c.second)
-        os << ", " << c.second->speak();
+    if (c.__node_)
+        os << ", " << c.__node_->speak();
+else
+        os << ", null";
     return os;
 }
 
-template <class _BidirectionalIterator> class sub_match;
 
-// __state
+// __node
 
 template <class _CharT>
-class __state
+class __node
 {
-    __state(const __state&);
-    __state& operator=(const __state&);
+    __node(const __node&);
+    __node& operator=(const __node&);
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
-    __state() {}
-    virtual ~__state() {}
+    __node() {}
+    virtual ~__node() {}
 
-    virtual __command __test(const _CharT* __first, const _CharT* __current,
-                             const _CharT* __last,
-                             vector<size_t>& __lc,
-                             sub_match<const _CharT*>* __m,
-                             regex_constants::match_flag_type __flags) const = 0;
+    virtual void __exec(__state&) const {};
+    virtual void __exec_split(bool, __state&) const {};
 
-    virtual string speak() const = 0;
+    virtual string speak() const {return "__node";}
 };
 
 // __end_state
 
 template <class _CharT>
 class __end_state
-    : public __state<_CharT>
+    : public __node<_CharT>
 {
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
     __end_state() {}
 
-    virtual __command __test(const _CharT*, const _CharT*,
-                             const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
+    virtual void __exec(__state&) const;
 
     virtual string speak() const {return "end state";}
 };
 
 template <class _CharT>
-__command<_CharT>
-__end_state<_CharT>::__test(const _CharT*, const _CharT*,
-                            const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                            regex_constants::match_flag_type) const
+void
+__end_state<_CharT>::__exec(__state& __s) const
 {
-    return __command(__command::__end_state);
+    __s.__do_ = __state::__end_state;
 }
 
 // __has_one_state
 
 template <class _CharT>
 class __has_one_state
-    : public __state<_CharT>
+    : public __node<_CharT>
 {
-    __state<_CharT>* __first_;
+    __node<_CharT>* __first_;
 
 public:
-    explicit __has_one_state(__state<_CharT>* __s)
+    explicit __has_one_state(__node<_CharT>* __s)
         : __first_(__s) {}
 
-    __state<_CharT>*  first() const {return __first_;}
-    __state<_CharT>*& first()       {return __first_;}
+    __node<_CharT>*  first() const {return __first_;}
+    __node<_CharT>*& first()       {return __first_;}
 };
 
 // __owns_one_state
@@ -1345,7 +1334,7 @@
     typedef __has_one_state<_CharT> base;
 
 public:
-    explicit __owns_one_state(__state<_CharT>* __s)
+    explicit __owns_one_state(__node<_CharT>* __s)
         : base(__s) {}
 
     virtual ~__owns_one_state();
@@ -1366,28 +1355,22 @@
     typedef __owns_one_state<_CharT> base;
 
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
-    explicit __empty_state(__state<_CharT>* __s)
+    explicit __empty_state(__node<_CharT>* __s)
         : base(__s) {}
 
-    virtual __command __test(const _CharT*, const _CharT*,
-                             const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
+    virtual void __exec(__state&) const;
 
     virtual string speak() const {return "empty state";}
 };
 
 template <class _CharT>
-__command<_CharT>
-__empty_state<_CharT>::__test(const _CharT*, const _CharT*, const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const
+void
+__empty_state<_CharT>::__exec(__state& __s) const
 {
-    return __command(__command::__accept_but_not_consume, this->first());
+    __s.__do_ = __state::__accept_but_not_consume;
+    __s.__node_ = this->first();
 }
 
 // __empty_non_own_state
@@ -1399,28 +1382,49 @@
     typedef __has_one_state<_CharT> base;
 
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
-    explicit __empty_non_own_state(__state<_CharT>* __s)
+    explicit __empty_non_own_state(__node<_CharT>* __s)
         : base(__s) {}
 
-    virtual __command __test(const _CharT*, const _CharT*,
-                             const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
+    virtual void __exec(__state&) const;
 
     virtual string speak() const {return "empty non-owning state";}
 };
 
 template <class _CharT>
-__command<_CharT>
-__empty_non_own_state<_CharT>::__test(const _CharT*, const _CharT*, const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const
+void
+__empty_non_own_state<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__accept_but_not_consume;
+    __s.__node_ = this->first();
+}
+
+// __repeat_one_loop
+
+template <class _CharT>
+class __repeat_one_loop
+    : public __has_one_state<_CharT>
+{
+    typedef __has_one_state<_CharT> base;
+
+public:
+    typedef _STD::__state<_CharT> __state;
+
+    explicit __repeat_one_loop(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual void __exec(__state&) const;
+
+    virtual string speak() const {return "repeat loop";}
+};
+
+template <class _CharT>
+void
+__repeat_one_loop<_CharT>::__exec(__state& __s) const
 {
-    return __command(__command::__accept_but_not_consume, this->first());
+    __s.__do_ = __state::__repeat;
+    __s.__node_ = this->first();
 }
 
 // __owns_two_states
@@ -1434,7 +1438,7 @@
     base* __second_;
 
 public:
-    explicit __owns_two_states(__state<_CharT>* __s1, base* __s2)
+    explicit __owns_two_states(__node<_CharT>* __s1, base* __s2)
         : base(__s1), __second_(__s2) {}
 
     virtual ~__owns_two_states();
@@ -1460,307 +1464,248 @@
     size_t __min_;
     size_t __max_;
     unsigned __loop_id_;
+    unsigned __mexp_begin_;
+    unsigned __mexp_end_;
     bool __greedy_;
 
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
     explicit __loop(unsigned __loop_id,
-                          __state<_CharT>* __s1, __owns_one_state<_CharT>* __s2,
+                          __node<_CharT>* __s1, __owns_one_state<_CharT>* __s2,
+                          unsigned __mexp_begin, unsigned __mexp_end,
                           bool __greedy = true,
                           size_t __min = 0,
                           size_t __max = numeric_limits<size_t>::max())
         : base(__s1, __s2), __min_(__min), __max_(__max), __loop_id_(__loop_id),
+          __mexp_begin_(__mexp_begin), __mexp_end_(__mexp_end),
           __greedy_(__greedy) {}
 
-    virtual __command __test(const _CharT* __first, const _CharT* __current,
-                             const _CharT* __last,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type __flags) const;
+    virtual void __exec(__state& __s) const;
+    virtual void __exec_split(bool __second, __state& __s) const;
 
     virtual string speak() const
     {
         ostringstream os;
-        os << "loop {" << __min_ << ',' << __max_ << "}";
+        os << "loop "<< __loop_id_ << " {" << __min_ << ',' << __max_ << "}";
         if (!__greedy_)
             os << " not";
         os << " greedy";
         return os.str();
     }
-};
-
-template <class _CharT>
-__command<_CharT>
-__loop<_CharT>::__test(const _CharT* __first, const _CharT* __current,
-                             const _CharT* __last,
-                             vector<size_t>& __lc,
-                             sub_match<const _CharT*>* __m,
-                             regex_constants::match_flag_type __flags) const
-{
-    size_t __count = __lc[__loop_id_];
-    if (__min_ <= __count && __count < __max_)
-        if (__greedy_)
-            return __command(__command::__accept_but_not_consume, this->first(),
-                                                                  this->second());
-        else
-            return __command(__command::__accept_but_not_consume, this->second(),
-                                                                  this->first());
-    if (__min_ <= __count)
-        return __command(__command::__accept_but_not_consume, this->second());
-    if (__count < __max_)
-        return __command(__command::__accept_but_not_consume, this->first());
-    throw regex_error(regex_constants::error_temp);
-}
-
-// __zero_loop_count
-
-template <class _CharT>
-class __zero_loop_count
-    : public __owns_one_state<_CharT>
-{
-    typedef __owns_one_state<_CharT> base;
-
-    size_t __loop_id_;
 
-public:
-    typedef _STD::__command<_CharT> __command;
-
-    explicit __zero_loop_count(size_t __loop_id,
-                          __state<_CharT>* __s1)
-        : base(__s1), __loop_id_(__loop_id) {}
-
-    virtual __command __test(const _CharT*, const _CharT*, const _CharT*,
-                             vector<size_t>& __lc,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
-
-    virtual string speak() const
+private:
+    void __init_repeat(__state& __s) const
     {
-        ostringstream os;
-        os << "zero loop " << __loop_id_;
-        return os.str();
+        __s.__loop_data_[__loop_id_].second = __s.__current_;
+        for (size_t __i = __mexp_begin_-1; __i != __mexp_end_-1; ++__i)
+        {
+            __s.__sub_matches_[__i].first = __s.__last_;
+            __s.__sub_matches_[__i].second = __s.__last_;
+            __s.__sub_matches_[__i].matched = false;
+        }
     }
 };
 
 template <class _CharT>
-__command<_CharT>
-__zero_loop_count<_CharT>::__test(const _CharT*, const _CharT*, const _CharT*,
-                             vector<size_t>& __lc,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const
+void
+__loop<_CharT>::__exec(__state& __s) const
 {
-    __lc[__loop_id_] = 0;
-    return __command(__command::__accept_but_not_consume, this->first());
+    if (__s.__do_ == __state::__repeat)
+    {
+        bool __do_repeat = ++__s.__loop_data_[__loop_id_].first < __max_;
+        bool __do_alt = __s.__loop_data_[__loop_id_].first >= __min_;
+        if (__do_repeat && __do_alt &&
+                               __s.__loop_data_[__loop_id_].second == __s.__current_)
+            __do_repeat = false;
+        if (__do_repeat && __do_alt)
+            __s.__do_ = __state::__split;
+        else if (__do_repeat)
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__node_ = this->first();
+            __init_repeat(__s);
+        }
+        else
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__node_ = this->second();
+        }
+    }
+    else
+    {
+        if (__max_ > 0)
+            __s.__do_ = __state::__split;
+        else
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__node_ = this->second();
+        }
+    }
 }
 
-// __increment_loop_count
-
 template <class _CharT>
-class __increment_loop_count
-    : public __has_one_state<_CharT>
+void
+__loop<_CharT>::__exec_split(bool __second, __state& __s) const
 {
-    typedef __has_one_state<_CharT> base;
-
-    size_t __loop_id_;
-
-public:
-    typedef _STD::__command<_CharT> __command;
-
-    explicit __increment_loop_count(size_t __loop_id,
-                          __state<_CharT>* __s1)
-        : base(__s1), __loop_id_(__loop_id) {}
-
-    virtual __command __test(const _CharT*, const _CharT*, const _CharT*,
-                             vector<size_t>& __lc,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
-
-    virtual string speak() const
+    __s.__do_ = __state::__accept_but_not_consume;
+    if (__greedy_ != __second)
     {
-        ostringstream os;
-        os << "increment loop " << __loop_id_;
-        return os.str();
+        __s.__node_ = this->first();
+        __init_repeat(__s);
     }
-};
-
-template <class _CharT>
-__command<_CharT>
-__increment_loop_count<_CharT>::__test(const _CharT*, const _CharT*, const _CharT*,
-                             vector<size_t>& __lc,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const
-{
-    ++__lc[__loop_id_];
-    return __command(__command::__accept_but_not_consume, this->first());
+    else
+        __s.__node_ = this->second();
 }
 
-// __zero_marked_exprs
+// __begin_marked_subexpression
 
 template <class _CharT>
-class __zero_marked_exprs
+class __begin_marked_subexpression
     : public __owns_one_state<_CharT>
 {
     typedef __owns_one_state<_CharT> base;
 
-    size_t __begin_;
-    size_t __end_;
-
+    unsigned __mexp_;
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
-    explicit __zero_marked_exprs(size_t __begin, size_t __end,
-                          __state<_CharT>* __s1)
-        : base(__s1), __begin_(__begin), __end_(__end) {}
+    explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
+        : base(__s), __mexp_(__mexp) {}
 
-    virtual __command __test(const _CharT*, const _CharT*, const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>* __sm,
-                             regex_constants::match_flag_type) const;
+    virtual void __exec(__state&) const;
 
     virtual string speak() const
     {
         ostringstream os;
-        os << "zero marked exprs [" << __begin_ << ',' << __end_ << ')';
+        os << "begin marked expr " << __mexp_;
         return os.str();
     }
 };
 
 template <class _CharT>
-__command<_CharT>
-__zero_marked_exprs<_CharT>::__test(const _CharT*, const _CharT*,
-                             const _CharT* __last,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>* __sm,
-                             regex_constants::match_flag_type) const
-{
-    for (size_t __i = __begin_; __i != __end_; ++__i)
-    {
-        __sm[__i].first = __last;
-        __sm[__i].second = __last;
-        __sm[__i].matched = false;
-    }
-    return __command(__command::__accept_but_not_consume, this->first());
+void
+__begin_marked_subexpression<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__accept_but_not_consume;
+    __s.__sub_matches_[__mexp_-1].first = __s.__current_;
+    __s.__node_ = this->first();
 }
 
-// __begin_marked_subexpression
+// __end_marked_subexpression
 
 template <class _CharT>
-class __begin_marked_subexpression
+class __end_marked_subexpression
     : public __owns_one_state<_CharT>
 {
     typedef __owns_one_state<_CharT> base;
 
     unsigned __mexp_;
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
-    explicit __begin_marked_subexpression(unsigned __mexp, __state<_CharT>* __s)
+    explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
         : base(__s), __mexp_(__mexp) {}
 
-    virtual __command __test(const _CharT*, const _CharT*,
-                             const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
+    virtual void __exec(__state&) const;
 
     virtual string speak() const
     {
         ostringstream os;
-        os << "begin marked expr " << __mexp_;
+        os << "end marked expr " << __mexp_;
         return os.str();
     }
 };
 
 template <class _CharT>
-__command<_CharT>
-__begin_marked_subexpression<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>* __s,
-                             regex_constants::match_flag_type) const
+void
+__end_marked_subexpression<_CharT>::__exec(__state& __s) const
 {
-    __s[__mexp_].first = __c;
-    return __command(__command::__accept_but_not_consume, this->first());
+    __s.__do_ = __state::__accept_but_not_consume;
+    __s.__sub_matches_[__mexp_-1].second = __s.__current_;
+    __s.__sub_matches_[__mexp_-1].matched = true;
+    __s.__node_ = this->first();
 }
 
-// __end_marked_subexpression
+// __r_anchor
 
 template <class _CharT>
-class __end_marked_subexpression
+class __r_anchor
     : public __owns_one_state<_CharT>
 {
     typedef __owns_one_state<_CharT> base;
 
-    unsigned __mexp_;
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
-    explicit __end_marked_subexpression(unsigned __mexp, __state<_CharT>* __s)
-        : base(__s), __mexp_(__mexp) {}
+    __r_anchor(__node<_CharT>* __s)
+        : base(__s) {}
 
-    virtual __command __test(const _CharT*, const _CharT*,
-                             const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
+    virtual void __exec(__state&) const;
 
     virtual string speak() const
     {
         ostringstream os;
-        os << "end marked expr " << __mexp_;
+        os << "right anchor";
         return os.str();
     }
 };
 
 template <class _CharT>
-__command<_CharT>
-__end_marked_subexpression<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>* __s,
-                             regex_constants::match_flag_type) const
-{
-    __s[__mexp_].second = __c;
-    __s[__mexp_].matched = true;
-    return __command(__command::__accept_but_not_consume, this->first());
+void
+__r_anchor<_CharT>::__exec(__state& __s) const
+{
+    if (__s.__current_ == __s.__last_)
+    {
+        __s.__do_ = __state::__accept_but_not_consume;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
 }
 
-// __r_anchor
+// __match_any
 
 template <class _CharT>
-class __r_anchor
+class __match_any
     : public __owns_one_state<_CharT>
 {
     typedef __owns_one_state<_CharT> base;
 
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
-    __r_anchor(__state<_CharT>* __s)
+    __match_any(__node<_CharT>* __s)
         : base(__s) {}
 
-    virtual __command __test(const _CharT*, const _CharT* __c,
-                             const _CharT* __l,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
+    virtual void __exec(__state&) const;
 
     virtual string speak() const
     {
         ostringstream os;
-        os << "right anchor";
+        os << "match any";
         return os.str();
     }
 };
 
 template <class _CharT>
-__command<_CharT>
-__r_anchor<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT* __l,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const
+void
+__match_any<_CharT>::__exec(__state& __s) const
 {
-    return __c == __l ?
-        __command(__command::__accept_but_not_consume, this->first()) : __command();
+    if (__s.__current_ != __s.__last_ && *__s.__current_ != 0)
+    {
+        __s.__do_ = __state::__accept_and_consume;
+        ++__s.__current_;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
 }
 
 // __match_char
@@ -1776,16 +1721,12 @@
     __match_char(const __match_char&);
     __match_char& operator=(const __match_char&);
 public:
-    typedef _STD::__command<_CharT> __command;
+    typedef _STD::__state<_CharT> __state;
 
-    __match_char(_CharT __c, __state<_CharT>* __s)
+    __match_char(_CharT __c, __node<_CharT>* __s)
         : base(__s), __c_(__c) {}
 
-    virtual __command __test(const _CharT*, const _CharT* __c,
-                             const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const;
+    virtual void __exec(__state&) const;
 
     virtual string speak() const
     {
@@ -1796,15 +1737,20 @@
 };
 
 template <class _CharT>
-__command<_CharT>
-__match_char<_CharT>::__test(const _CharT*, const _CharT* __c,
-                             const _CharT*,
-                             vector<size_t>&,
-                             sub_match<const _CharT*>*,
-                             regex_constants::match_flag_type) const
+void
+__match_char<_CharT>::__exec(__state& __s) const
 {
-    return __c_ == *__c ?
-        __command(__command::__accept_and_consume, this->first()) : __command();
+    if (__s.__current_ != __s.__last_ && *__s.__current_ == __c_)
+    {
+        __s.__do_ = __state::__accept_and_consume;
+        ++__s.__current_;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
 }
 
 template <class, class> class match_results;
@@ -1828,8 +1774,8 @@
     __owns_one_state<_CharT>* __end_;
     bool __left_anchor_;
 
-    typedef _STD::__command<_CharT> __command;
     typedef _STD::__state<_CharT> __state;
+    typedef _STD::__node<_CharT> __node;
 
 public:
     // constants:
@@ -2008,7 +1954,7 @@
 
     void __push_l_anchor() {__left_anchor_ = true;}
     void __push_r_anchor();
-    void __push_match_any() {}
+    void __push_match_any();
     void __push_greedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s,
                                   unsigned __mexp_begin = 0, unsigned __mexp_end = 0)
         {__push_loop(__min, numeric_limits<size_t>::max(), __s,
@@ -2080,7 +2026,7 @@
                                       _ForwardIterator __last)
 {
     {
-        unique_ptr<__state> __h(new __end_state<_CharT>);
+        unique_ptr<__node> __h(new __end_state<_CharT>);
         __start_.reset(new __empty_state<_CharT>(__h.get()));
         __h.release();
         __end_ = __start_.get();
@@ -2897,29 +2843,14 @@
 {
     unique_ptr<__empty_state<_CharT> > __e1(new __empty_state<_CharT>(__end_->first()));
     __end_->first() = nullptr;
-    unique_ptr<__loop<_CharT> > __e2;
-    if (__mexp_begin != __mexp_end)
-    {
-        unique_ptr<__zero_marked_exprs<_CharT> >
-                __e3(new __zero_marked_exprs<_CharT>(__mexp_begin, __mexp_end,
-                                                     __s->first()));
-        __s->first() = nullptr;
-        __e2.reset(new __loop<_CharT>(__loop_count_, __e3.get(), __e1.get(),
-                                      __greedy, __min, __max));
-        __e3.release();
-        __e1.release();
-    }
-    else
-    {
-        __e2.reset(new __loop<_CharT>(__loop_count_, __s->first(), __e1.get(),
-                                      __greedy, __min, __max));
-        __s->first() = nullptr;
-        __e1.release();
-    }
-    __end_->first() = new __increment_loop_count<_CharT>(__loop_count_, __e2.get());
+    unique_ptr<__loop<_CharT> > __e2(new __loop<_CharT>(__loop_count_,
+                __s->first(), __e1.get(), __mexp_begin, __mexp_end, __greedy,
+                __min, __max));
+    __s->first() = nullptr;
+    __e1.release();
+    __end_->first() = new __repeat_one_loop<_CharT>(__e2.get());
     __end_ = __e2->second();
-    __s->first() = new __zero_loop_count<_CharT>(__loop_count_, __e2.get());
-    __e2.release();
+    __s->first() = __e2.release();
     ++__loop_count_;
 }
 
@@ -2957,6 +2888,13 @@
     __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
 }
 
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_match_any()
+{
+    __end_->first() = new __match_any<_CharT>(__end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
 
 typedef basic_regex<char>    regex;
 typedef basic_regex<wchar_t> wregex;
@@ -3539,50 +3477,73 @@
         regex_constants::match_flag_type __flags) const
 {
     typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
-    __split_buffer<__command> __commands;
+    deque<__state> __states;
     difference_type __j = 0;
     difference_type __highest_j = 0;
     difference_type _N = _STD::distance(__first, __last);
-    __state* __st = __start_.get();
+    __node* __st = __start_.get();
     if (__st)
     {
-        __commands.push_front(__command(__st));
-        __commands.push_front(__command(__command::__consume_input));
+        __states.push_back(__state());
+        __states.back().__do_ = __state::__consume_input;
+        __states.push_back(__state());
+        __states.back().__do_ = 0;
+        __states.back().__first_ = __first;
+        __states.back().__current_ = __first;
+        __states.back().__last_ = __last;
+        __states.back().__loop_data_.resize(__loop_count());
+        __states.back().__node_ = __st;
+        __states.back().__flags_ = __flags;
         _BidirectionalIterator __current = __first;
         do
         {
-            __command __cmd = __commands.back();
-            __commands.pop_back();
-            if (__cmd.first != nullptr)
-                __cmd = __cmd.first->__test(__first, __current, __last, __lc,
-                                            __m.__matches_.data(), __flags);
-            switch (__cmd.__do_)
+            __state& __s = __states.back();
+            if (__s.__node_)
+                __s.__node_->__exec(__s);
+            switch (__s.__do_)
             {
-            case __command::__end_state:
+            case __state::__end_state:
                 __highest_j = _STD::max(__highest_j, __j);
+                if (__highest_j == _N)
+                    __states.clear();
+                else
+                    __states.pop_back();
                 break;
-            case __command::__consume_input:
+            case __state::__consume_input:
                 if (__j == _N)
                     return false;
                 ++__current;
-                if (++__j != _N && !__commands.empty())
-                    __commands.push_front(__command(__command::__consume_input));
+                if (++__j != _N && __states.size() > 1)
+                    __states.push_front(_STD::move(__s));
+                __states.pop_back();
+                break;
+            case __state::__accept_and_consume:
+                // needs to be changed for the case that this state
+                // consumed more than one character.  This will scan
+                // down the deque and insert extra __consume_input
+                // states as necessary
+                __states.push_front(_STD::move(__s));
+                __states.pop_back();
                 break;
-            case __command::__accept_and_consume:
-                __commands.push_front(__command(__cmd.first));
+            case __state::__repeat:
+            case __state::__accept_but_not_consume:
                 break;
-            case __command::__accept_but_not_consume:
-                __commands.push_back(__command(__cmd.first));
-                if (__cmd.second != nullptr)
-                    __commands.push_back(__command(__cmd.second));
+            case __state::__split:
+                {
+                __state __snext = __s;
+                __s.__node_->__exec_split(true, __s);
+                __snext.__node_->__exec_split(false, __snext);
+                __states.push_back(_STD::move(__snext));
+                }
                 break;
-            case __command::__reject:
+            case __state::__reject:
+                __states.pop_back();
                 break;
             default:
                 throw regex_error(regex_constants::error_temp);
                 break;
             }
-        } while (!__commands.empty());
+        } while (!__states.empty());
         if (__highest_j != 0)
         {
             __m.__matches_[0].first = __first;
@@ -3604,83 +3565,82 @@
         regex_constants::match_flag_type __flags) const
 {
     typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
-    vector<__command> __commands;
+    vector<__state> __states;
     vector<_BidirectionalIterator> __current_stack;
     vector<sub_match<_BidirectionalIterator> > __saved_matches;
-    vector<sub_match<_BidirectionalIterator> > __best_matches;
+    __state __best_state;
     difference_type __j = 0;
     difference_type __highest_j = 0;
     difference_type _N = _STD::distance(__first, __last);
-    __state* __st = __start_.get();
+    __node* __st = __start_.get();
     if (__st)
     {
-        __commands.push_back(__command(__st));
+        __states.push_back(__state());
+        __states.back().__do_ = 0;
+        __states.back().__first_ = __first;
+        __states.back().__current_ = __first;
+        __states.back().__last_ = __last;
+        __states.back().__sub_matches_.resize(mark_count());
+        __states.back().__loop_data_.resize(__loop_count());
+        __states.back().__node_ = __st;
+        __states.back().__flags_ = __flags;
         _BidirectionalIterator __current = __first;
+        bool __matched = false;
         do
         {
-            __command __cmd = __commands.back();
-            __commands.pop_back();
-            if (__cmd.first != nullptr)
-                __cmd = __cmd.first->__test(__first, __current, __last, __lc,
-                                            __m.__matches_.data(), __flags);
-            switch (__cmd.__do_)
+            __state& __s = __states.back();
+            if (__s.__node_)
+                __s.__node_->__exec(__s);
+            switch (__s.__do_)
             {
-            case __command::__end_state:
-                if (__highest_j < __j)
+            case __state::__end_state:
+                if (__j == 0 || __highest_j < __j)
                 {
+                    __matched = true;
                     __highest_j = __j;
-                    for (unsigned __i = 1; __i < __m.__matches_.size(); ++__i)
-                        __best_matches.push_back(__m.__matches_[__i]);
-                }
-                break;
-            case __command::__pop_state:
-                for (unsigned __i = __m.__matches_.size(); __i > 1;)
-                {
-                    assert(!__saved_matches.empty());
-                    __m.__matches_[--__i] = __saved_matches.back();
-                    __saved_matches.pop_back();
+                    __best_state = __s;
+                    if (__highest_j == _N || __highest_j == 0)
+                        __states.clear();
+                    else
+                        __states.pop_back();
                 }
-                assert(!__current_stack.empty());
-                __current = __current_stack.back();
-                __current_stack.pop_back();
                 break;
-            case __command::__accept_and_consume:
-                __commands.push_back(__command(__cmd.first));
+            case __state::__accept_and_consume:
+                // needs to be changed for the case that this state
+                // consumed more than one character.  This will adjust
+                // __current based on __s.__current_
                 if (__current != __last)
                 {
                     ++__current;
                     ++__j;
                 }
                 break;
-            case __command::__accept_but_not_consume:
-                if (__cmd.second != nullptr)
+            case __state::__repeat:
+            case __state::__accept_but_not_consume:
+                break;
+            case __state::__split:
                 {
-                    __commands.push_back(__command(__cmd.second));
-                    __commands.push_back(__command(__command::__pop_state));
-                    __current_stack.push_back(__current);
-                    for (unsigned __i = 1; __i < __m.__matches_.size(); ++__i)
-                        __saved_matches.push_back(__m.__matches_[__i]);
+                __state __snext = __s;
+                __s.__node_->__exec_split(true, __s);
+                __snext.__node_->__exec_split(false, __snext);
+                __states.push_back(_STD::move(__snext));
                 }
-                __commands.push_back(__command(__cmd.first));
                 break;
-            case __command::__reject:
+            case __state::__reject:
+                __states.pop_back();
                 break;
             default:
                 throw regex_error(regex_constants::error_temp);
                 break;
             }
-        } while (!__commands.empty());
-        if (__highest_j != 0)
+        } while (!__states.empty());
+        if (__matched)
         {
             __m.__matches_[0].first = __first;
             __m.__matches_[0].second = _STD::next(__first, __highest_j);
             __m.__matches_[0].matched = true;
-            for (unsigned __i = __m.__matches_.size(); __i > 1;)
-            {
-                assert(!__best_matches.empty());
-                __m.__matches_[--__i] = __best_matches.back();
-                __best_matches.pop_back();
-            }
+            for (unsigned __i = 0; __i < __best_state.__sub_matches_.size(); ++__i)
+                __m.__matches_[__i+1] = __best_state.__sub_matches_[__i];
             return true;
         }
     }

Modified: libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp?rev=108151&r1=108150&r2=108151&view=diff
==============================================================================
--- libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp (original)
+++ libcxx/trunk/test/re/re.alg/re.alg.search/basic.pass.cpp Mon Jul 12 10:51:17 2010
@@ -229,4 +229,85 @@
         assert(!std::regex_search(s, m, std::regex("abc$", std::regex_constants::basic)));
         assert(m.size() == 0);
     }
+    {
+        std::cmatch m;
+        const char s[] = "abc";
+        assert(std::regex_search(s, m, std::regex("a.c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == s+3);
+        assert(m.length(0) == 3);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "acc";
+        assert(std::regex_search(s, m, std::regex("a.c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == s+3);
+        assert(m.length(0) == 3);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "acc";
+        assert(std::regex_search(s, m, std::regex("a.c", std::regex_constants::basic)));
+        assert(m.size() == 1);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == s+3);
+        assert(m.length(0) == 3);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "abcdef";
+        assert(std::regex_search(s, m, std::regex("\\(.*\\).*", std::regex_constants::basic)));
+        assert(m.size() == 2);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(!m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == s+6);
+        assert(m.length(0) == 6);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
+        assert(m.length(1) == 6);
+        assert(m.position(1) == 0);
+        assert(m.str(1) == s);
+    }
+    {
+        std::cmatch m;
+        const char s[] = "bc";
+        assert(std::regex_search(s, m, std::regex("\\(a*\\)*", std::regex_constants::basic)));
+        assert(m.size() == 2);
+        assert(!m.prefix().matched);
+        assert(m.prefix().first == s);
+        assert(m.prefix().second == m[0].first);
+        assert(m.suffix().matched);
+        assert(m.suffix().first == m[0].second);
+        assert(m.suffix().second == s+2);
+        assert(m.length(0) == 0);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == "");
+        assert(m.length(1) == 0);
+        assert(m.position(1) == 0);
+        assert(m.str(1) == "");
+    }
 }





More information about the cfe-commits mailing list