Continuing to work through regex, and updated libcxx_by_chapter.pdf with weekly test results

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@106790 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/regex b/include/regex
index e48f072..0277774 100644
--- a/include/regex
+++ b/include/regex
@@ -720,6 +720,7 @@
 #include <__config>
 #include <stdexcept>
 #include <__locale>
+#include <initializer_list>
 
 #pragma GCC system_header
 
@@ -895,7 +896,8 @@
     error_space,
     error_badrepeat,
     error_complexity,
-    error_stack
+    error_stack,
+    error_temp
 };
 
 }  // regex_constants
@@ -1193,7 +1195,7 @@
         {
             __ch |= 0x20;  // tolower
             if ('a' <= __ch && __ch <= 'f')
-                return __ch - 'a' + 10;
+                return __ch - ('a' - 10);
         }
     }
     return -1;
@@ -1207,6 +1209,510 @@
     return __value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
 }
 
+template <class _CharT, class _Traits = regex_traits<_CharT> >
+class basic_regex
+{
+public:
+    // types:
+    typedef _CharT                              value_type;
+    typedef regex_constants::syntax_option_type flag_type;
+    typedef typename _Traits::locale_type       locale_type;
+
+private:
+    _Traits   __traits_;
+    flag_type __flags_;
+    unsigned __marked_count_;
+
+public:
+    // constants:
+    static const/*expr*/ regex_constants::syntax_option_type icase = regex_constants::icase;
+    static const/*expr*/ regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
+    static const/*expr*/ regex_constants::syntax_option_type optimize = regex_constants::optimize;
+    static const/*expr*/ regex_constants::syntax_option_type collate = regex_constants::collate;
+    static const/*expr*/ regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
+    static const/*expr*/ regex_constants::syntax_option_type basic = regex_constants::basic;
+    static const/*expr*/ regex_constants::syntax_option_type extended = regex_constants::extended;
+    static const/*expr*/ regex_constants::syntax_option_type awk = regex_constants::awk;
+    static const/*expr*/ regex_constants::syntax_option_type grep = regex_constants::grep;
+    static const/*expr*/ regex_constants::syntax_option_type egrep = regex_constants::egrep;
+
+    // construct/copy/destroy:
+    basic_regex();
+    explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
+        : __flags_(__f), __marked_count_(0)
+        {__parse(__p, __p + __traits_.length(__p));}
+    basic_regex(const value_type* __p, size_t __len, flag_type __f)
+        : __flags_(__f), __marked_count_(0)
+        {__parse(__p, __p + __len);}
+    basic_regex(const basic_regex&);
+#ifdef _LIBCPP_MOVE
+    basic_regex(basic_regex&&);
+#endif
+    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)
+        {__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)
+        {__parse(__first, __last);}
+    basic_regex(initializer_list<value_type> __il,
+                flag_type __f = regex_constants::ECMAScript)
+        : __flags_(__f), __marked_count_(0)
+        {__parse(__il.begin(), __il.end());}
+
+    ~basic_regex();
+
+    basic_regex& operator=(const basic_regex&);
+#ifdef _LIBCPP_MOVE
+    basic_regex& operator=(basic_regex&&);
+#endif
+    basic_regex& operator=(const value_type* __p);
+    basic_regex& operator=(initializer_list<value_type> __il);
+    template <class _ST, class _SA>
+        basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p);
+
+    // assign:
+    basic_regex& assign(const basic_regex& __that);
+#ifdef _LIBCPP_MOVE
+    basic_regex& assign(basic_regex&& __that);
+#endif
+    basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript);
+    basic_regex& assign(const value_type* __p, size_t __len, flag_type __f);
+    template <class _ST, class _SA>
+        basic_regex& assign(const basic_string<value_type, _ST, _SA>& __s,
+                            flag_type __f = regex_constants::ECMAScript);
+    template <class _InputIterator>
+        basic_regex& assign(_InputIterator __first, _InputIterator __last,
+                            flag_type __f = regex_constants::ECMAScript);
+    basic_regex& assign(initializer_list<value_type> __il,
+                        flag_type = regex_constants::ECMAScript);
+
+    // const operations:
+    unsigned mark_count() const {return __marked_count_;}
+    flag_type flags() const {return __flags_;}
+
+    // locale:
+    locale_type imbue(locale_type __loc) {return __traits_.imbue(__loc);}
+    locale_type getloc() const {return __traits_.getloc();}
+
+    // swap:
+    void swap(basic_regex&);
+
+private:
+    template <class _ForwardIterator>
+        void __parse(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last);
+
+    void __push_l_anchor();
+    void __push_r_anchor();
+    void __push_match_any();
+    void __push_greedy_inf_repeat(int __min);
+    void __push_exact_repeat(int __count);
+    void __push_repeat(int __min, int __max);
+};
+
+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()
+{
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+void
+basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
+                                      _ForwardIterator __last)
+{
+    switch (__flags_ & 0x3F0)
+    {
+    case ECMAScript:
+        break;
+    case basic:
+        __parse_basic_reg_exp(__first, __last);
+        break;
+    case extended:
+        break;
+    case awk:
+        break;
+    case grep:
+        break;
+    case egrep:
+        break;
+    default:
+        throw regex_error(regex_constants::error_temp);
+    }
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first,
+                                                    _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        if (*__first == '^')
+        {
+            __push_l_anchor();
+            ++__first;
+        }
+        if (__first != __last)
+        {
+            __first = __parse_RE_expression(__first, __last);
+            if (__first != __last)
+            {
+                _ForwardIterator __temp = next(__first);
+                if (__temp == __last && *__first == '$')
+                {
+                    __push_r_anchor();
+                    ++__first;
+                }
+            }
+        }
+        if (__first != __last)
+            throw regex_error(regex_constants::error_temp);
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first,
+                                                    _ForwardIterator __last)
+{
+    while (true)
+    {
+        _ForwardIterator __temp = __parse_simple_RE(__first, __last);
+        if (__temp == __first)
+            break;
+        __first = __temp;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first,
+                                                _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = __parse_nondupl_RE(__first, __last);
+        if (__temp != __first)
+        {
+            __first = __temp;
+            __first = __parse_RE_dupl_symbol(__first, __last);
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first,
+                                                 _ForwardIterator __last)
+{
+    _ForwardIterator __temp = __first;
+    __first = __parse_one_char_or_coll_elem_RE(__first, __last);
+    if (__temp == __first)
+    {
+        __temp = __parse_Back_open_paren(__first, __last);
+        if (__temp != __first)
+        {
+            __first = __parse_RE_expression(__temp, __last);
+            __temp = __parse_Back_close_paren(__first, __last);
+            if (__temp == __first)
+                throw regex_error(regex_constants::error_paren);
+            __first = __temp;
+            ++__marked_count_;
+        }
+        else
+            __first = __parse_BACKREF(__first, __last);
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE(
+                                                       _ForwardIterator __first,
+                                                       _ForwardIterator __last)
+{
+    _ForwardIterator __temp = __first;
+    __first = __parse_ORD_CHAR(__first, __last);
+    if (__temp == __first)
+    {
+        __first = __parse_QUOTED_CHAR(__first, __last);
+        if (__temp == __first)
+        {
+            if (__first != __last && *__first == '.')
+            {
+                __push_match_any();
+                ++__first;
+            }
+            else
+                __first = __parse_bracket_expression(__first, __last);
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first,
+                                                      _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && *__temp == '(')
+                __first = ++__temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first,
+                                                       _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && *__temp == ')')
+                __first = ++__temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first,
+                                                      _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && *__temp == '{')
+                __first = ++__temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first,
+                                                       _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && *__temp == '}')
+                __first = ++__temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first,
+                                              _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && '1' <= *__temp && *__temp <= '9')
+            {
+                __push_back_ref(*__temp - '0');
+                __first = ++__temp;
+            }
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first,
+                                               _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = next(__first);
+        if (__temp == __last && *__first == '$')
+            return __first;
+        // Not called inside a bracket
+        if (*__first == '.' || *__first == '\\' || *__first == '[')
+            return __first;
+        __push_ord_char(*__first);
+        ++__first;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first,
+                                                  _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\')
+            {
+                switch (*__temp)
+                {
+                case '^':
+                case '.':
+                case '*':
+                case '[':
+                case '$':
+                case '\\':
+                    __push_ord_char(*__temp);
+                    __first = ++__temp;
+                    break;
+                }
+            }
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first,
+                                                     _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        if (__first == '*')
+        {
+            __push_greedy_inf_repeat(0);
+            ++__first;
+        }
+        else
+        {
+            _ForwardIterator __temp = __parse_Back_open_brace(__first, __last);
+            if (__temp != __first)
+            {
+                int __min = 0;
+                __first = __temp;
+                __temp = __parse_DUP_COUNT(__first, __last, __min);
+                if (__temp == __first)
+                    throw regex_error(regex_constants::error_badbrace);
+                __first = __temp;
+                if (__first == __last)
+                    throw regex_error(regex_constants::error_brace);
+                if (*__first != ',')
+                {
+                    __temp = __parse_Back_close_brace(__first, __last);
+                    if (__temp == __first)
+                        throw regex_error(regex_constants::error_brace);
+                    __push_exact_repeat(__min);
+                    __first = __temp;
+                }
+                else
+                {
+                    ++__first;  // consume ','
+                    int __max = -1;
+                    __first = __parse_DUP_COUNT(__first, __last, __max);
+                    __temp = __parse_Back_close_brace(__first, __last);
+                    if (__temp == __first)
+                        throw regex_error(regex_constants::error_brace);
+                    if (__max == -1)
+                        __push_greedy_inf_repeat(__min);
+                    else
+                    {
+                        if (__max < __min)
+                            throw regex_error(regex_constants::error_badbrace);
+                        __push_repeat(__min, __max);
+                    }
+                    __first = __temp;
+                }
+            }
+        }
+    }
+    return __first;
+}
+
+typedef basic_regex<char>    regex;
+typedef basic_regex<wchar_t> wregex;
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_REGEX