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

Howard Hinnant hhinnant at apple.com
Wed Jul 7 12:14:52 PDT 2010


Author: hhinnant
Date: Wed Jul  7 14:14:52 2010
New Revision: 107803

URL: http://llvm.org/viewvc/llvm-project?rev=107803&view=rev
Log:
First loop test passed.  The data structure and search algorithm is still crude and in-flux.  But this milestone needed to be locked in.  Right now every loop is implemented in terms of a structure that will handle the most complicated {min, max} loop.  Though only *-loops are tested at the moment.  In a future iteration *-loops will likely be optimized a little more.  The only tests are for basic posix so far, but I have prototype code running for extended posix and ecma.  The prototype code lacks the complicating properties of the real <regex> requirements though.

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

Modified: libcxx/trunk/include/__split_buffer
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__split_buffer?rev=107803&r1=107802&r2=107803&view=diff
==============================================================================
--- libcxx/trunk/include/__split_buffer (original)
+++ libcxx/trunk/include/__split_buffer Wed Jul  7 14:14:52 2010
@@ -18,7 +18,7 @@
     void __throw_out_of_range() const;
 };
 
-template <class _Tp, class _Allocator>
+template <class _Tp, class _Allocator = allocator<_Tp> >
 struct __split_buffer
     : private __split_buffer_common<true>
 {
@@ -497,7 +497,7 @@
         else
         {
             size_type __c = max<size_type>(2 * (__end_cap() - __first_), 1);
-            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 2) / 4, __alloc());
+            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
             __t.__construct_at_end(move_iterator<pointer>(__begin_),
                                    move_iterator<pointer>(__end_));
             _STD::swap(__first_, __t.__first_);
@@ -528,7 +528,7 @@
         else
         {
             size_type __c = max<size_type>(2 * (__end_cap() - __first_), 1);
-            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 2) / 4, __alloc());
+            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
             __t.__construct_at_end(move_iterator<pointer>(__begin_),
                                    move_iterator<pointer>(__end_));
             _STD::swap(__first_, __t.__first_);

Modified: libcxx/trunk/include/regex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/regex?rev=107803&r1=107802&r2=107803&view=diff
==============================================================================
--- libcxx/trunk/include/regex (original)
+++ libcxx/trunk/include/regex Wed Jul  7 14:14:52 2010
@@ -726,6 +726,7 @@
 #include <string>
 #include <memory>
 #include <vector>
+#include <__split_buffer>
 
 #pragma GCC system_header
 
@@ -1214,214 +1215,520 @@
     return __value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
 }
 
-template <class _CharT> class __transition;
+template <class _CharT> class __state;
 
 template <class _CharT>
-class __state
+struct __command
 {
-    typedef __transition<_CharT> __transition;
-    __transition* __t1_;
-    __transition* __t2_;
-    int __state_;
     enum
     {
-        __not_tried = 0,
-        __1_succeded = 1,
-        __1_failed = 2,
-        __2_not_tried = 0,
-        __2_succeded = 4,
-        __2_failed = 8
+        __end_state = -1000,
+        __consume_input,  // -999
+//        __try_state,      // -998
+        __begin_marked_expr, // -998
+        __end_marked_expr,   // -997
+        __go_back,           // -996
+        __accept_and_consume,  // -995
+        __accept_but_not_consume,  // -994
+        __reject,                  // -993
+        __zero_loop_count,
+        __increment_loop_count,
+        __zero_marked_exprs,
     };
 
+    typedef __state<_CharT> __state;
+
+    int __do_;
+    int __data_;
+    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) {}
+};
+
+template <class _BidirectionalIterator> class sub_match;
+
+// __state
+
+template <class _CharT>
+class __state
+{
     __state(const __state&);
     __state& operator=(const __state&);
 public:
-    __state()
-        : __t1_(), __t2_(), __state_() {}
-    ~__state();
+    typedef __command<_CharT> __command;
+
+    __state() {}
+    virtual ~__state() {}
+
+    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;
+};
 
-    __state* __test(_CharT __c, bool& __consume, unsigned& __begin_sub,
-                                                 unsigned& __end_sub);
+// __end_state
+
+template <class _CharT>
+class __end_state
+    : public __state<_CharT>
+{
+public:
+    typedef __command<_CharT> __command;
 
-    void __add_one(__transition* __t) {__t1_ = __t;}
+    __end_state() {}
 
-    void __reset_state();
+    virtual __command __test(const _CharT*, const _CharT*,
+                             const _CharT*,
+                             vector<size_t>&,
+                             sub_match<const _CharT*>*,
+                             regex_constants::match_flag_type) const;
 };
 
 template <class _CharT>
-__state<_CharT>::~__state()
+__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
 {
-    delete __t1_;
-    delete __t2_;
+    return __command(__command::__end_state);
 }
 
+// __has_one_state
+
 template <class _CharT>
-__state<_CharT>*
-__state<_CharT>::__test(_CharT __c, bool& __consume, unsigned& __begin_sub,
-                                                     unsigned& __end_sub)
+class __has_one_state
+    : public __state<_CharT>
 {
-    __state* __r = nullptr;
-    if ((__state_ & 3) == 0)
-    {
-        if (__t1_)
-        {
-            __r = __t1_->__test(__c, __consume, __begin_sub, __end_sub);
-            if (__r)
-                __state_ |= __1_succeded;
-            else
-                __state_ |= __1_failed;
-        }
-        else
-            __state_ |= __1_failed;
-    }
-    else if ((__state_ & 0xC) == 0)
-    {
-        if (__t2_)
-        {
-            __r = __t2_->__test(__c, __consume, __begin_sub, __end_sub);
-            if (__r)
-                __state_ |= __2_succeded;
-            else
-                __state_ |= __2_failed;
-        }
-        else
-            __state_ |= __2_failed;
-    }
-    return __r;
+    __state<_CharT>* __first_;
+
+public:
+    explicit __has_one_state(__state<_CharT>* __s)
+        : __first_(__s) {}
+
+    __state<_CharT>*  first() const {return __first_;}
+    __state<_CharT>*& first()       {return __first_;}
+};
+
+// __owns_one_state
+
+template <class _CharT>
+class __owns_one_state
+    : public __has_one_state<_CharT>
+{
+    typedef __has_one_state<_CharT> base;
+
+public:
+    explicit __owns_one_state(__state<_CharT>* __s)
+        : base(__s) {}
+
+    virtual ~__owns_one_state();
+};
+
+template <class _CharT>
+__owns_one_state<_CharT>::~__owns_one_state()
+{
+    delete this->first();
 }
 
+// __empty_state
+
 template <class _CharT>
-void
-__state<_CharT>::__reset_state()
+class __empty_state
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+public:
+    typedef __command<_CharT> __command;
+
+    explicit __empty_state(__state<_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;
+};
+
+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
 {
-    __state_ = __not_tried;
-    if (__t1_)
-        __t1_->__reset_state();
-    if (__t2_)
-        __t2_->__reset_state();
+    return __command(__command::__accept_but_not_consume, this->first());
 }
 
+// __empty_non_own_state
+
 template <class _CharT>
-class __transition
+class __empty_non_own_state
+    : public __has_one_state<_CharT>
 {
-    __transition(const __transition&);
-    __transition& operator=(const __transition&);
+    typedef __has_one_state<_CharT> base;
 
-protected:
-    typedef __state<_CharT> __state;
-    typedef unique_ptr<__state, void(*)(__state*)> __sptr;
+public:
+    typedef __command<_CharT> __command;
+
+    explicit __empty_non_own_state(__state<_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;
+};
+
+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
+{
+    return __command(__command::__accept_but_not_consume, this->first());
+}
+
+// __owns_two_states
+
+template <class _CharT>
+class __owns_two_states
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
 
-    static void __delete_state(__state* __p) {delete __p;}
-    static void __ignore_state(__state*) {}
+    base* __second_;
 
-    __sptr __sptr_;
 public:
-    __transition(bool __owns, __state* __st)
-        : __sptr_(__st, __owns ? &__delete_state : &__ignore_state) {}
-    virtual ~__transition() {}
+    explicit __owns_two_states(__state<_CharT>* __s1, base* __s2)
+        : base(__s1), __second_(__s2) {}
 
-    virtual __state* __test(_CharT, bool& __consume, unsigned& __begin_sub,
-                                                     unsigned& __end_sub);
+    virtual ~__owns_two_states();
 
-    void __reset_state();
+    base*  second() const {return __second_;}
+    base*& second()       {return __second_;}
 };
 
 template <class _CharT>
-typename __transition<_CharT>::__state*
-__transition<_CharT>::__test(_CharT, bool& __consume, unsigned&, unsigned&)
+__owns_two_states<_CharT>::~__owns_two_states()
 {
-    __consume = false;
-    return __sptr_.get();
+    delete __second_;
 }
- 
+
+// __loop
+
 template <class _CharT>
-void
-__transition<_CharT>::__reset_state()
+class __loop
+    : public __owns_two_states<_CharT>
 {
-    if (__sptr_.get_deleter() == &__delete_state)
-        __sptr_->__reset_state();
+    typedef __owns_two_states<_CharT> base;
+
+    size_t __min_;
+    size_t __max_;
+    unsigned __loop_id_;
+    bool __greedy_;
+
+public:
+    typedef __command<_CharT> __command;
+
+    explicit __loop(unsigned __loop_id,
+                          __state<_CharT>* __s1, __owns_one_state<_CharT>* __s2,
+                          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),
+          __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;
+};
+
+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 __match_char
-    : public __transition<_CharT>
+class __zero_loop_count
+    : public __owns_one_state<_CharT>
 {
-    typedef __transition<_CharT> base;
-    _CharT __c_;
+    typedef __owns_one_state<_CharT> base;
+
+    size_t __loop_id_;
+
 public:
-    typedef typename base::__state __state;
+    typedef __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;
+};
+
+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
+{
+    __lc[__loop_id_] = 0;
+    return __command(__command::__accept_but_not_consume, this->first());
+}
+
+// __increment_loop_count
+
+template <class _CharT>
+class __increment_loop_count
+    : public __has_one_state<_CharT>
+{
+    typedef __has_one_state<_CharT> base;
 
-    __match_char(_CharT __c, bool __owns, __state* __st)
-        : base(__owns, __st), __c_(__c) {}
+    size_t __loop_id_;
+
+public:
+    typedef __command<_CharT> __command;
 
-    virtual __state* __test(_CharT __c, bool& __consume, unsigned&, unsigned&);
+    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;
 };
 
 template <class _CharT>
-typename __match_char<_CharT>::__state*
-__match_char<_CharT>::__test(_CharT __c, bool& __consume, unsigned&, unsigned&)
+__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
 {
-    if (__c == __c_)
+    ++__lc[__loop_id_];
+    return __command(__command::__accept_but_not_consume, this->first());
+}
+
+// __zero_marked_exprs
+
+template <class _CharT>
+class __zero_marked_exprs
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    size_t __begin_;
+    size_t __end_;
+
+public:
+    typedef __command<_CharT> __command;
+
+    explicit __zero_marked_exprs(size_t __begin, size_t __end,
+                          __state<_CharT>* __s1)
+        : base(__s1), __begin_(__begin), __end_(__end) {}
+
+    virtual __command __test(const _CharT*, const _CharT*, const _CharT*,
+                             vector<size_t>&,
+                             sub_match<const _CharT*>* __sm,
+                             regex_constants::match_flag_type) const;
+};
+
+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)
     {
-        __consume = true;
-        return base::__sptr_.get();
+        __sm[__i].first = __last;
+        __sm[__i].second = __last;
+        __sm[__i].matched = false;
     }
-    __consume = false;
-    return nullptr;
+    return __command(__command::__accept_but_not_consume, this->first());
 }
- 
+
+// __begin_marked_subexpression
+
 template <class _CharT>
 class __begin_marked_subexpression
-    : public __transition<_CharT>
+    : public __owns_one_state<_CharT>
 {
-    typedef __transition<_CharT> base;
-    unsigned __sub_;
+    typedef __owns_one_state<_CharT> base;
+
+    __begin_marked_subexpression(const __begin_marked_subexpression&);
+    __begin_marked_subexpression& operator=(const __begin_marked_subexpression&);
 public:
-    typedef typename base::__state __state;
+    typedef __command<_CharT> __command;
 
-    __begin_marked_subexpression(unsigned __sub, bool __owns, __state* __st)
-        : base(__owns, __st), __sub_(__sub) {}
+    explicit __begin_marked_subexpression(__state<_CharT>* __s)
+        : base(__s) {}
 
-    virtual __state* __test(_CharT, bool& __consume, unsigned& __begin_sub,
-                                                     unsigned&);
+    virtual __command __test(const _CharT*, const _CharT*,
+                             const _CharT*,
+                             vector<size_t>&,
+                             sub_match<const _CharT*>*,
+                             regex_constants::match_flag_type) const;
 };
 
 template <class _CharT>
-typename __begin_marked_subexpression<_CharT>::__state*
-__begin_marked_subexpression<_CharT>::__test(_CharT, bool& __consume,
-                                             unsigned& __begin_sub, unsigned&)
+__command<_CharT>
+__begin_marked_subexpression<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT*,
+                             vector<size_t>&,
+                             sub_match<const _CharT*>*,
+                             regex_constants::match_flag_type) const
 {
-    __consume = false;
-    __begin_sub = __sub_;
-    return base::__sptr_.get();
+    return __command(__command::__begin_marked_expr, this->first());
 }
- 
+
+// __end_marked_subexpression
+
 template <class _CharT>
 class __end_marked_subexpression
-    : public __transition<_CharT>
+    : public __owns_one_state<_CharT>
 {
-    typedef __transition<_CharT> base;
-    unsigned __sub_;
+    typedef __owns_one_state<_CharT> base;
+
+    __end_marked_subexpression(const __end_marked_subexpression&);
+    __end_marked_subexpression& operator=(const __end_marked_subexpression&);
 public:
-    typedef typename base::__state __state;
+    typedef __command<_CharT> __command;
 
-    __end_marked_subexpression(unsigned __sub, bool __owns, __state* __st)
-        : base(__owns, __st), __sub_(__sub) {}
+    explicit __end_marked_subexpression(__state<_CharT>* __s)
+        : base(__s) {}
 
-    virtual __state* __test(_CharT, bool& __consume, unsigned&,
-                                                     unsigned& __end_sub);
+    virtual __command __test(const _CharT*, const _CharT*,
+                             const _CharT*,
+                             vector<size_t>&,
+                             sub_match<const _CharT*>*,
+                             regex_constants::match_flag_type) const;
 };
 
 template <class _CharT>
-typename __end_marked_subexpression<_CharT>::__state*
-__end_marked_subexpression<_CharT>::__test(_CharT, bool& __consume,
-                                           unsigned&, unsigned& __end_sub)
+__command<_CharT>
+__end_marked_subexpression<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT*,
+                             vector<size_t>&,
+                             sub_match<const _CharT*>*,
+                             regex_constants::match_flag_type) const
 {
-    __consume = false;
-    __end_sub = __sub_;
-    return base::__sptr_.get();
+    return __command(__command::__end_marked_expr, this->first());
 }
- 
+
+// __state_arg
+
+template <class _CharT>
+class __state_arg
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    unsigned __arg_;
+
+    __state_arg(const __state_arg&);
+    __state_arg& operator=(const __state_arg&);
+public:
+    typedef __command<_CharT> __command;
+
+    __state_arg(unsigned __a, __state<_CharT>* __s)
+        : base(__s), __arg_(__a) {}
+
+    virtual __command __test(const _CharT*, const _CharT*,
+                             const _CharT*,
+                             vector<size_t>&,
+                             sub_match<const _CharT*>*,
+                             regex_constants::match_flag_type) const;
+};
+
+template <class _CharT>
+__command<_CharT>
+__state_arg<_CharT>::__test(const _CharT*, const _CharT* __c, const _CharT*,
+                             vector<size_t>&,
+                             sub_match<const _CharT*>*,
+                             regex_constants::match_flag_type) const
+{
+    return __command(__arg_, this->first());
+}
+
+// __match_char
+
+template <class _CharT>
+class __match_char
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    _CharT __c_;
+
+    __match_char(const __match_char&);
+    __match_char& operator=(const __match_char&);
+public:
+    typedef __command<_CharT> __command;
+
+    __match_char(_CharT __c, __state<_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;
+};
+
+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
+{
+    return __c_ == *__c ?
+        __command(__command::__accept_and_consume, this->first()) : __command();
+}
+
 template <class, class> class match_results;
 
 template <class _CharT, class _Traits = regex_traits<_CharT> >
@@ -1437,9 +1744,13 @@
     _Traits   __traits_;
     flag_type __flags_;
     unsigned __marked_count_;
+    unsigned __loop_count_;
     int __open_count_;
-    shared_ptr<__state<_CharT> > __start_;
-    __state<_CharT>* __end_;
+    shared_ptr<__empty_state<_CharT> > __start_;
+    __owns_one_state<_CharT>* __end_;
+
+    typedef __command<_CharT> __command;
+    typedef __state<_CharT> __state;
 
 public:
     // constants:
@@ -1455,12 +1766,14 @@
     static const/*expr*/ regex_constants::syntax_option_type egrep = regex_constants::egrep;
 
     // construct/copy/destroy:
-    basic_regex();
+    basic_regex()
+        : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
+        {}
     explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
-        : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
         {__parse(__p, __p + __traits_.length(__p));}
     basic_regex(const value_type* __p, size_t __len, flag_type __f)
-        : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
         {__parse(__p, __p + __len);}
     basic_regex(const basic_regex&);
 #ifdef _LIBCPP_MOVE
@@ -1469,16 +1782,16 @@
     template <class _ST, class _SA>
         explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,
                              flag_type __f = regex_constants::ECMAScript)
-        : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
         {__parse(__p.begin(), __p.end());}
     template <class _ForwardIterator>
         basic_regex(_ForwardIterator __first, _ForwardIterator __last,
                     flag_type __f = regex_constants::ECMAScript)
-        : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
         {__parse(__first, __last);}
     basic_regex(initializer_list<value_type> __il,
                 flag_type __f = regex_constants::ECMAScript)
-        : __flags_(__f), __marked_count_(0), __open_count_(0), __end_(0)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0)
         {__parse(__il.begin(), __il.end());}
 
     ~basic_regex();
@@ -1520,6 +1833,8 @@
     void swap(basic_regex&);
 
 private:
+    unsigned __loop_count() const {return __loop_count_;}
+
     template <class _ForwardIterator>
         void __parse(_ForwardIterator __first, _ForwardIterator __last);
     template <class _ForwardIterator>
@@ -1560,7 +1875,8 @@
         __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last);
     template <class _ForwardIterator>
         _ForwardIterator
-        __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last);
+        __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last,
+                               __owns_one_state<_CharT>* __s);
     template <class _ForwardIterator>
         _ForwardIterator
         __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last);
@@ -1607,9 +1923,12 @@
     void __push_l_anchor() {}
     void __push_r_anchor() {}
     void __push_match_any() {}
-    void __push_greedy_inf_repeat(int __min) {}
+    void __push_greedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s)
+        {__push_loop(__min, numeric_limits<size_t>::max(), __s);}
     void __push_exact_repeat(int __count) {}
-    void __push_repeat(int __min, int __max) {}
+    void __push_loop(size_t __min, size_t __max, __owns_one_state<_CharT>* __s,
+                     size_t __mexp_begin = 0, size_t __mexp_end = 0,
+                     bool __greedy = true);
     void __start_nonmatching_list() {}
     void __start_matching_list() {}
     void __end_nonmatching_list() {}
@@ -1629,19 +1948,36 @@
                  match_results<_BidirectionalIterator, _Allocator>& __m,
                  regex_constants::match_flag_type __flags) const;
 
+    template <class _BidirectionalIterator, class _Allocator>
+        bool
+        __match_at_start(_BidirectionalIterator __first, _BidirectionalIterator __last,
+                 match_results<_BidirectionalIterator, _Allocator>& __m,
+                 vector<size_t>& __lc,
+                 regex_constants::match_flag_type __flags) const;
+    template <class _BidirectionalIterator, class _Allocator>
+        bool
+        __match_at_start_ecma(_BidirectionalIterator __first, _BidirectionalIterator __last,
+                 match_results<_BidirectionalIterator, _Allocator>& __m,
+                 regex_constants::match_flag_type __flags) const;
+    template <class _BidirectionalIterator, class _Allocator>
+        bool
+        __match_at_start_posix_nosubs(const _CharT* __first, const _CharT* __last,
+                 match_results<_BidirectionalIterator, _Allocator>& __m,
+                 vector<size_t>& __lc,
+                 regex_constants::match_flag_type __flags) const;
+    template <class _BidirectionalIterator, class _Allocator>
+        bool
+        __match_at_start_posix_subs(_BidirectionalIterator __first, _BidirectionalIterator __last,
+                 match_results<_BidirectionalIterator, _Allocator>& __m,
+                 regex_constants::match_flag_type __flags) const;
+
     template <class _B, class _A, class _C, class _T>
     friend
     bool
     regex_search(_B, _B, match_results<_B, _A>&, const basic_regex<_C, _T>&,
                  regex_constants::match_flag_type);
-};
 
-template <class _CharT, class _Traits>
-inline
-basic_regex<_CharT, _Traits>::basic_regex()
-    : __traits_(), __flags_(), __marked_count_(0)
-{
-}
+};
 
 template <class _CharT, class _Traits>
 basic_regex<_CharT, _Traits>::~basic_regex()
@@ -1654,6 +1990,12 @@
 basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
                                       _ForwardIterator __last)
 {
+    {
+        unique_ptr<__state> __h(new __end_state<_CharT>);
+        __start_.reset(new __empty_state<_CharT>(__h.get()));
+        __h.release();
+        __end_ = __start_.get();
+    }
     switch (__flags_ & 0x3F0)
     {
     case ECMAScript:
@@ -1808,12 +2150,10 @@
 {
     if (__first != __last)
     {
+        __owns_one_state<_CharT>* __e = __end_;
         _ForwardIterator __temp = __parse_nondupl_RE(__first, __last);
         if (__temp != __first)
-        {
-            __first = __temp;
-            __first = __parse_RE_dupl_symbol(__first, __last);
-        }
+            __first = __parse_RE_dupl_symbol(__temp, __last, __e);
     }
     return __first;
 }
@@ -2121,13 +2461,14 @@
 template <class _ForwardIterator>
 _ForwardIterator
 basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first,
-                                                     _ForwardIterator __last)
+                                                     _ForwardIterator __last,
+                                                     __owns_one_state<_CharT>* __s)
 {
     if (__first != __last)
     {
         if (*__first == '*')
         {
-            __push_greedy_inf_repeat(0);
+            __push_greedy_inf_repeat(0, __s);
             ++__first;
         }
         else
@@ -2160,12 +2501,12 @@
                     if (__temp == __first)
                         throw regex_error(regex_constants::error_brace);
                     if (__max == -1)
-                        __push_greedy_inf_repeat(__min);
+                        __push_greedy_inf_repeat(__min, __s);
                     else
                     {
                         if (__max < __min)
                             throw regex_error(regex_constants::error_badbrace);
-                        __push_repeat(__min, __max);
+                        __push_loop(__min, __max, __s);
                     }
                     __first = __temp;
                 }
@@ -2186,15 +2527,15 @@
         switch (*__first)
         {
         case '*':
-            __push_greedy_inf_repeat(0);
+            __push_greedy_inf_repeat(0, nullptr);
             ++__first;
             break;
         case '+':
-            __push_greedy_inf_repeat(1);
+            __push_greedy_inf_repeat(1, nullptr);
             ++__first;
             break;
         case '?':
-            __push_repeat(0, 1);
+            __push_loop(0, 1, nullptr);
             ++__first;
             break;
         case '{':
@@ -2217,7 +2558,7 @@
                         throw regex_error(regex_constants::error_badbrace);
                     if (*__first == '}')
                     {
-                        __push_greedy_inf_repeat(__min);
+                        __push_greedy_inf_repeat(__min, nullptr);
                         ++__first;
                     }
                     else
@@ -2232,7 +2573,7 @@
                         ++__first;
                         if (__max < __min)
                             throw regex_error(regex_constants::error_badbrace);
-                        __push_repeat(__min, __max);
+                        __push_loop(__min, __max, nullptr);
                     }
                 default:
                     throw regex_error(regex_constants::error_badbrace);
@@ -2457,53 +2798,73 @@
 
 template <class _CharT, class _Traits>
 void
+basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max,
+        __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end,
+        bool __greedy)
+{
+    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());
+    __end_ = __e2->second();
+    __s->first() = new __zero_loop_count<_CharT>(__loop_count_, __e2.get());
+    __e2.release();
+    ++__loop_count_;
+}
+
+template <class _CharT, class _Traits>
+void
 basic_regex<_CharT, _Traits>::__push_char(value_type __c)
 {
-    unique_ptr<__state<_CharT> > __new_end(new __state<_CharT>);
-    unique_ptr<__transition<_CharT> > __new_transition(
-        new __match_char<_CharT>(__c, true, __new_end.get()));
-    __state<_CharT>* __e = __new_end.release();
-    if (__end_ == nullptr)
-    {
-        __start_.reset(new __state<_CharT>);
-        __end_ = __start_.get();
-    }
-    __end_->__add_one(__new_transition.release());
-    __end_ = __e;
+    __match_char<_CharT>* __s = new __match_char<_CharT>(__c, __end_->first());
+    __end_->first() = __s;
+    __end_ = __s;
 }
 
 template <class _CharT, class _Traits>
 void
 basic_regex<_CharT, _Traits>::__push_begin_marked_subexpression()
 {
-    unique_ptr<__state<_CharT> > __new_end(new __state<_CharT>);
-    unique_ptr<__transition<_CharT> > __new_transition(
-        new __begin_marked_subexpression<_CharT>(++__marked_count_, true, __new_end.get()));
-    __state<_CharT>* __e = __new_end.release();
-    if (__end_ == nullptr)
-    {
-        __start_.reset(new __state<_CharT>);
-        __end_ = __start_.get();
-    }
-    __end_->__add_one(__new_transition.release());
-    __end_ = __e;
+    __begin_marked_subexpression<_CharT>* __s =
+                     new __begin_marked_subexpression<_CharT>(__end_->first());
+    __end_->first() = __s;
+    __end_ = __s;
+    __state_arg<_CharT>* __a = new __state_arg<_CharT>(++__marked_count_,
+                                                               __end_->first());
+    __end_->first() = __a;
+    __end_ = __a;
 }
 
 template <class _CharT, class _Traits>
 void
 basic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub)
 {
-    unique_ptr<__state<_CharT> > __new_end(new __state<_CharT>);
-    unique_ptr<__transition<_CharT> > __new_transition(
-        new __end_marked_subexpression<_CharT>(__sub, true, __new_end.get()));
-    __state<_CharT>* __e = __new_end.release();
-    if (__end_ == nullptr)
-    {
-        __start_.reset(new __state<_CharT>);
-        __end_ = __start_.get();
-    }
-    __end_->__add_one(__new_transition.release());
-    __end_ = __e;
+    __end_marked_subexpression<_CharT>* __s =
+                        new __end_marked_subexpression<_CharT>(__end_->first());
+    __end_->first() = __s;
+    __end_ = __s;
+    __state_arg<_CharT>* __a = new __state_arg<_CharT>(++__marked_count_,
+                                                               __end_->first());
+    __end_->first() = __a;
+    __end_ = __a;
 }
 
 typedef basic_regex<char>    regex;
@@ -3034,16 +3395,10 @@
 match_results<_BidirectionalIterator, _Allocator>::__init(unsigned __s,
                          _BidirectionalIterator __f, _BidirectionalIterator __l)
 {
-    __matches_.resize(__s);
-    for (unsigned __i = 0; __i < __s; ++__i)
-    {
-        __matches_[__i].first   = __l;
-        __matches_[__i].second  = __l;
-        __matches_[__i].matched = false;
-    }
     __unmatched_.first   = __l;
     __unmatched_.second  = __l;
     __unmatched_.matched = false;
+    __matches_.assign(__s, __unmatched_);
     __prefix_.first      = __f;
     __prefix_.second     = __f;
     __prefix_.matched    = false;
@@ -3077,72 +3432,154 @@
 template <class _CharT, class _Traits>
 template <class _BidirectionalIterator, class _Allocator>
 bool
+basic_regex<_CharT, _Traits>::__match_at_start_ecma(
+        _BidirectionalIterator __first, _BidirectionalIterator __last,
+        match_results<_BidirectionalIterator, _Allocator>& __m,
+        regex_constants::match_flag_type __flags) const
+{
+    return false;
+}
+
+template <class _CharT, class _Traits>
+template <class _BidirectionalIterator, class _Allocator>
+bool
+basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
+        const _CharT* __first, const _CharT* __last,
+        match_results<_BidirectionalIterator, _Allocator>& __m,
+        vector<size_t>& __lc,
+        regex_constants::match_flag_type __flags) const
+{
+/*
+    How do you set __m.__matches[i].first and second?
+    With const _CharT* [__first, __last), we need a reference
+    _BidirectionalIterator to bounce off of.  Something like:
+    __m.__matches_[0].second = next(__m.__matches_[0].first, __current - __first_);
+
+    Pre:  __m.__matches_[0].first <-> __first ? or
+          __m.__prefix_.first <-> first and
+          __m.__suffix_.second <-> last ?
+*/
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    __split_buffer<__command> __commands;
+    difference_type __j = 0;
+    difference_type __highest_j = 0;
+    difference_type _N = _STD::distance(__first, __last);
+    __state* __st = __start_.get();
+    if (__st)
+    {
+        __commands.push_front(__command(__st));
+        __commands.push_front(__command(__command::__consume_input));
+        _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_)
+            {
+            case __command::__end_state:
+                __highest_j = _STD::max(__highest_j, __j);
+                break;
+            case __command::__consume_input:
+                if (__j == _N)
+                    return false;
+                ++__current;
+                if (++__j != _N && !__commands.empty())
+                    __commands.push_front(__command(__command::__consume_input));
+                break;
+            case __command::__accept_and_consume:
+                __commands.push_front(__command(__cmd.first));
+                if (__cmd.second != nullptr)
+                    __commands.push_front(__command(__cmd.second));
+                break;
+            case __command::__accept_but_not_consume:
+                __commands.push_back(__command(__cmd.first));
+                if (__cmd.second != nullptr)
+                    __commands.push_back(__command(__cmd.second));
+                break;
+            case __command::__reject:
+                break;
+            default:
+                throw regex_error(regex_constants::error_temp);
+                break;
+            }
+        } while (!__commands.empty());
+        if (__highest_j != 0)
+        {
+            __m.__matches_[0].first = __first;
+            __m.__matches_[0].second = _STD::next(__first, __highest_j);
+            __m.__matches_[0].matched = true;
+            return true;
+        }
+    }
+    return false;
+}
+
+template <class _CharT, class _Traits>
+template <class _BidirectionalIterator, class _Allocator>
+bool
+basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
+        _BidirectionalIterator __first, _BidirectionalIterator __last,
+        match_results<_BidirectionalIterator, _Allocator>& __m,
+        regex_constants::match_flag_type __flags) const
+{
+    return false;
+}
+
+template <class _CharT, class _Traits>
+template <class _BidirectionalIterator, class _Allocator>
+bool
+basic_regex<_CharT, _Traits>::__match_at_start(
+        _BidirectionalIterator __first, _BidirectionalIterator __last,
+        match_results<_BidirectionalIterator, _Allocator>& __m,
+        vector<size_t>& __lc,
+        regex_constants::match_flag_type __flags) const
+{
+    if (__flags_ & ECMAScript)
+        return __match_at_start_ecma(__first, __last, __m, __flags);
+    if (mark_count() == 0)
+        return __match_at_start_posix_nosubs(__first, __last, __m, __lc, __flags);
+    return __match_at_start_posix_subs(__first, __last, __m, __flags);
+}
+
+template <class _CharT, class _Traits>
+template <class _BidirectionalIterator, class _Allocator>
+bool
 basic_regex<_CharT, _Traits>::__search(
         _BidirectionalIterator __first, _BidirectionalIterator __last,
         match_results<_BidirectionalIterator, _Allocator>& __m,
         regex_constants::match_flag_type __flags) const
 {
-    bool __r = false;
-    if (__start_)
+    __m.__init(1 + mark_count(), __first, __last);
+    vector<size_t> __lc(__loop_count());
+    if (__match_at_start(__first, __last, __m, __lc, __flags))
+    {
+        __m.__prefix_.second = __m[0].first;
+        __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
+        __m.__suffix_.first = __m[0].second;
+        __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
+        return true;
+    }
+    if (!(__flags & regex_constants::match_continuous))
     {
-        __m.__init(1 + mark_count(), __first, __last);
-        for (; __first != __last; ++__first)
+        __m.__matches_.assign(__m.size(), __m.__unmatched_);
+        for (++__first; __first != __last; ++__first)
         {
-            __start_->__reset_state();
-            unsigned __begin_sub = 0;
-            unsigned __end_sub = 0;
-            bool __consume;
-            __state<_CharT>* __st = __start_->__test(*__first, __consume,
-                                                     __begin_sub, __end_sub);
-            if (__st)
+            if (__match_at_start(__first, __last, __m, __lc, __flags))
             {
-                _BidirectionalIterator& __f = __m.__matches_[0].first;
-                _BidirectionalIterator& __l = __m.__matches_[0].second;
-                __f = __l = __first;
-                if (__begin_sub != 0)
-                    __m.__matches_[__begin_sub].first = __l;
-                if (__end_sub != 0)
-                {
-                    __m.__matches_[__end_sub].second = __l;
-                    __m.__matches_[__end_sub].matched = true;
-                }
-                if (__consume)
-                    ++__l;
-                while (__l != __last && __st != __end_)
-                {
-                    __begin_sub = 0;
-                    __end_sub = 0;
-                    __st = __st->__test(*__l, __consume, __begin_sub, __end_sub);
-                    if (__st == nullptr)
-                        break;
-                    if (__begin_sub != 0)
-                        __m.__matches_[__begin_sub].first = __l;
-                    if (__end_sub != 0)
-                    {
-                        __m.__matches_[__end_sub].second = __l;
-                        __m.__matches_[__end_sub].matched = true;
-                    }
-                    if (__consume)
-                        ++__l;
-                }
-                if (__st == __end_)
-                {
-                    __r = __m.__matches_[0].matched = true;
-                    __m.__prefix_.second = __first;
-                    __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
-                    __m.__suffix_.first = __l;
-                    __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
-                    break;
-                }
-                __m.__matches_.assign(__m.__matches_.size(), __m.__unmatched_);
+                __m.__prefix_.second = __m[0].first;
+                __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
+                __m.__suffix_.first = __m[0].second;
+                __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
+                return true;
             }
-            if (__flags & regex_constants::match_continuous)
-                break;
+            __m.__matches_.assign(__m.size(), __m.__unmatched_);
         }
     }
-    if (!__r)
-        __m.__matches_.clear();
-    return __r;
+    __m.__matches_.clear();
+    return false;
 }
 
 template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>

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=107803&r1=107802&r2=107803&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 Wed Jul  7 14:14:52 2010
@@ -104,24 +104,39 @@
     }
     {
         std::cmatch m;
-        const char s[] = "abcdefghijk";
-        assert(std::regex_search(s, m, std::regex("cd\\(\\(e\\)fg\\)hi",
-                                 std::regex_constants::basic)));
-        assert(m.size() == 3);
-        assert(m.prefix().matched);
+        const char s[] = "abbc";
+        assert(std::regex_search(s, m, std::regex("ab*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().matched);
         assert(m.suffix().first == m[0].second);
-        assert(m.suffix().second == s+std::regex_traits<char>::length(s));
-        assert(m.length(0) == 7);
-        assert(m.position(0) == 2);
-        assert(m.str(0) == "cdefghi");
-        assert(m.length(1) == 3);
-        assert(m.position(1) == 4);
-        assert(m.str(1) == "efg");
-        assert(m.length(2) == 1);
-        assert(m.position(2) == 4);
-        assert(m.str(2) == "e");
+        assert(m.suffix().second == s+4);
+        assert(m.length(0) == 4);
+        assert(m.position(0) == 0);
+        assert(m.str(0) == s);
     }
+//     {
+//         std::cmatch m;
+//         const char s[] = "abcdefghijk";
+//         assert(std::regex_search(s, m, std::regex("cd\\(\\(e\\)fg\\)hi",
+//                                  std::regex_constants::basic)));
+//         assert(m.size() == 3);
+//         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+std::regex_traits<char>::length(s));
+//         assert(m.length(0) == 7);
+//         assert(m.position(0) == 2);
+//         assert(m.str(0) == "cdefghi");
+//         assert(m.length(1) == 3);
+//         assert(m.position(1) == 4);
+//         assert(m.str(1) == "efg");
+//         assert(m.length(2) == 1);
+//         assert(m.position(2) == 4);
+//         assert(m.str(2) == "e");
+//     }
 }





More information about the cfe-commits mailing list