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

Howard Hinnant hhinnant at apple.com
Tue Jul 27 15:20:32 PDT 2010


Author: hhinnant
Date: Tue Jul 27 17:20:32 2010
New Revision: 109548

URL: http://llvm.org/viewvc/llvm-project?rev=109548&view=rev
Log:
lookahead for ecma

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

Modified: libcxx/trunk/include/regex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/regex?rev=109548&r1=109547&r2=109548&view=diff
==============================================================================
--- libcxx/trunk/include/regex (original)
+++ libcxx/trunk/include/regex Tue Jul 27 17:20:32 2010
@@ -2416,57 +2416,7 @@
     }
 }
 
-// __lookahead
-
-template <class _CharT, class _Traits>
-class __lookahead
-    : public __owns_one_state<_CharT>
-{
-    typedef __owns_one_state<_CharT> base;
-
-    _Traits __traits_;
-    bool __invert_;
-
-    __lookahead(const __lookahead&);
-    __lookahead& operator=(const __lookahead&);
-public:
-    typedef _STD::__state<_CharT> __state;
-
-    __lookahead(const _Traits& __traits, bool __invert, __node<_CharT>* __s)
-        : base(__s), __traits_(__traits), __invert_(__invert) {}
-
-    virtual void __exec(__state&) const;
-
-    virtual string speak() const
-    {
-        ostringstream os;
-        if (__invert_)
-            os << "lookahead";
-        else
-            os << "not lookahead";
-        return os.str();
-    }
-};
-
-template <class _CharT, class _Traits>
-void
-__lookahead<_CharT, _Traits>::__exec(__state& __s) const
-{
-//     match_results<const _CharT*> __m;
-//     __m.__init(1 + mark_count(), __s.__current_, __s.__last_);
-//     bool __matched = __exp_.__match_at_start_ecma(__s.__current_, __s.__last_,
-//                                                   __m, __s.__flags_);
-//     if (__matched != __invert_)
-//     {
-//         __s.__do_ = __state::__accept_but_not_consume;
-//         __s.__node_ = this->first();
-//     }
-//     else
-//     {
-//         __s.__do_ = __state::__reject;
-//         __s.__node_ = nullptr;
-//     }
-}
+template <class, class> class __lookahead;
 
 template <class _CharT, class _Traits = regex_traits<_CharT> >
 class basic_regex
@@ -2516,10 +2466,8 @@
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0), __left_anchor_(false)
         {__parse(__p, __p + __len);}
-    basic_regex(const basic_regex&);
-#ifdef _LIBCPP_MOVE
-    basic_regex(basic_regex&&);
-#endif
+//     basic_regex(const basic_regex&) = default;
+//     basic_regex(basic_regex&&) = default;
     template <class _ST, class _SA>
         explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,
                              flag_type __f = regex_constants::ECMAScript)
@@ -2540,10 +2488,8 @@
 
     ~basic_regex();
 
-    basic_regex& operator=(const basic_regex&);
-#ifdef _LIBCPP_MOVE
-    basic_regex& operator=(basic_regex&&);
-#endif
+//     basic_regex& operator=(const basic_regex&) = default;
+//     basic_regex& operator=(basic_regex&&) = default;
     basic_regex& operator=(const value_type* __p);
     basic_regex& operator=(initializer_list<value_type> __il);
     template <class _ST, class _SA>
@@ -2580,7 +2526,8 @@
     unsigned __loop_count() const {return __loop_count_;}
 
     template <class _ForwardIterator>
-        void __parse(_ForwardIterator __first, _ForwardIterator __last);
+        _ForwardIterator
+        __parse(_ForwardIterator __first, _ForwardIterator __last);
     template <class _ForwardIterator>
         _ForwardIterator
         __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
@@ -2732,7 +2679,7 @@
     void __push_end_marked_subexpression(unsigned);
     void __push_empty();
     void __push_word_boundary(bool);
-    void __push_lookahead(bool) {}
+    void __push_lookahead(const basic_regex&, bool);
 
     template <class _Allocator>
         bool
@@ -2805,6 +2752,8 @@
                  match_results<typename basic_string<_C, _ST, _SA>::const_iterator, _A>&, 
                  const basic_regex<_C, _T>& __e,
                  regex_constants::match_flag_type __flags);
+
+    template <class, class> friend class __lookahead;
 };
 
 template <class _CharT, class _Traits>
@@ -2812,9 +2761,61 @@
 {
 }
 
+// __lookahead
+
+template <class _CharT, class _Traits>
+class __lookahead
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    basic_regex<_CharT, _Traits> __exp_;
+    bool __invert_;
+
+    __lookahead(const __lookahead&);
+    __lookahead& operator=(const __lookahead&);
+public:
+    typedef _STD::__state<_CharT> __state;
+
+    __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s)
+        : base(__s), __exp_(__exp), __invert_(__invert) {}
+
+    virtual void __exec(__state&) const;
+
+    virtual string speak() const
+    {
+        ostringstream os;
+        if (__invert_)
+            os << "not lookahead";
+        else
+            os << "lookahead";
+        return os.str();
+    }
+};
+
 template <class _CharT, class _Traits>
-template <class _ForwardIterator>
 void
+__lookahead<_CharT, _Traits>::__exec(__state& __s) const
+{
+    match_results<const _CharT*> __m;
+    __m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_);
+    bool __matched = __exp_.__match_at_start_ecma(__s.__current_, __s.__last_,
+                                                  __m, __s.__flags_);
+    if (__matched != __invert_)
+    {
+        __s.__do_ = __state::__accept_but_not_consume;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
 basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
                                       _ForwardIterator __last)
 {
@@ -2827,25 +2828,26 @@
     switch (__flags_ & 0x1F0)
     {
     case ECMAScript:
-        __parse_ecma_exp(__first, __last);
+        __first = __parse_ecma_exp(__first, __last);
         break;
     case basic:
-        __parse_basic_reg_exp(__first, __last);
+        __first = __parse_basic_reg_exp(__first, __last);
         break;
     case extended:
-        __parse_extended_reg_exp(__first, __last);
+        __first = __parse_extended_reg_exp(__first, __last);
         break;
     case awk:
         break;
     case grep:
-        __parse_grep(__first, __last);
+        __first = __parse_grep(__first, __last);
         break;
     case egrep:
-        __parse_egrep(__first, __last);
+        __first = __parse_egrep(__first, __last);
         break;
     default:
         throw regex_error(regex_constants::__re_err_grammar);
     }
+    return __first;
 }
 
 template <class _CharT, class _Traits>
@@ -3816,18 +3818,28 @@
                         switch (*__temp)
                         {
                         case '=':
-                            __push_lookahead(false);
-                            __temp = __parse_ecma_exp(++__temp, __last);
-                            if (__temp == __last || *__temp != ')')
-                                throw regex_error(regex_constants::error_paren);
-                            __first = ++__temp;
+                            {
+                                basic_regex __exp;
+                                __exp.__flags_ = __flags_;
+                                __temp = __exp.__parse(++__temp, __last);
+                                __exp.__push_l_anchor();
+                                __push_lookahead(_STD::move(__exp), false);
+                                if (__temp == __last || *__temp != ')')
+                                    throw regex_error(regex_constants::error_paren);
+                                __first = ++__temp;
+                            }
                             break;
                         case '!':
-                            __push_lookahead(true);
-                            __temp = __parse_ecma_exp(++__temp, __last);
-                            if (__temp == __last || *__temp != ')')
-                                throw regex_error(regex_constants::error_paren);
-                            __first = ++__temp;
+                            {
+                                basic_regex __exp;
+                                __exp.__flags_ = __flags_;
+                                __temp = __exp.__parse(++__temp, __last);
+                                __exp.__push_l_anchor();
+                                __push_lookahead(_STD::move(__exp), true);
+                                if (__temp == __last || *__temp != ')')
+                                    throw regex_error(regex_constants::error_paren);
+                                __first = ++__temp;
+                            }
                             break;
                         }
                     }
@@ -4321,6 +4333,16 @@
     return __r;
 }
 
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_lookahead(const basic_regex& __exp,
+                                               bool __invert)
+{
+    __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert,
+                                                           __end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
 typedef basic_regex<char>    regex;
 typedef basic_regex<wchar_t> wregex;
 
@@ -4854,6 +4876,8 @@
     bool
     regex_match(_B, _B, match_results<_B, _A>&, const basic_regex<_C, _T>&,
                 regex_constants::match_flag_type);
+
+    template <class, class> friend class __lookahead;
 };
 
 template <class _BidirectionalIterator, class _Allocator>

Modified: libcxx/trunk/test/re/re.alg/re.alg.search/ecma.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/re/re.alg/re.alg.search/ecma.pass.cpp?rev=109548&r1=109547&r2=109548&view=diff
==============================================================================
--- libcxx/trunk/test/re/re.alg/re.alg.search/ecma.pass.cpp (original)
+++ libcxx/trunk/test/re/re.alg/re.alg.search/ecma.pass.cpp Tue Jul 27 17:20:32 2010
@@ -16,6 +16,8 @@
 //                  const basic_regex<charT, traits>& e,
 //                  regex_constants::match_flag_type flags = regex_constants::match_default);
 
+#include <iostream>
+
 #include <regex>
 #include <cassert>
 
@@ -756,6 +758,36 @@
         assert(m.position(0) == 0);
         assert(m.str(0) == s);
     }
+    {
+        std::cmatch m;
+        const char s[] = "Jeff Jeffs ";
+        assert(std::regex_search(s, m, std::regex("Jeff(?=s\\b)")));
+        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 + std::char_traits<char>::length(s));
+        assert(m.length(0) == 4);
+        assert(m.position(0) == 5);
+        assert(m.str(0) == "Jeff");
+    }
+    {
+        std::cmatch m;
+        const char s[] = "Jeffs Jeff";
+        assert(std::regex_search(s, m, std::regex("Jeff(?!s\\b)")));
+        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 + std::char_traits<char>::length(s));
+        assert(m.length(0) == 4);
+        assert(m.position(0) == 6);
+        assert(m.str(0) == "Jeff");
+    }
 
     {
         std::wcmatch m;
@@ -1490,4 +1522,34 @@
         assert(m.position(0) == 0);
         assert(m.str(0) == s);
     }
+    {
+        std::wcmatch m;
+        const wchar_t s[] = L"Jeff Jeffs ";
+        assert(std::regex_search(s, m, std::wregex(L"Jeff(?=s\\b)")));
+        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 + std::char_traits<wchar_t>::length(s));
+        assert(m.length(0) == 4);
+        assert(m.position(0) == 5);
+        assert(m.str(0) == L"Jeff");
+    }
+    {
+        std::wcmatch m;
+        const wchar_t s[] = L"Jeffs Jeff";
+        assert(std::regex_search(s, m, std::wregex(L"Jeff(?!s\\b)")));
+        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 + std::char_traits<wchar_t>::length(s));
+        assert(m.length(0) == 4);
+        assert(m.position(0) == 6);
+        assert(m.str(0) == L"Jeff");
+    }
 }





More information about the cfe-commits mailing list