Index: libcxx/include/regex =================================================================== --- libcxx/include/regex +++ libcxx/include/regex @@ -765,6 +765,8 @@ #include #include +#include <__debug> + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif @@ -1404,16 +1406,8 @@ _LIBCPP_INLINE_VISIBILITY explicit __owns_one_state(__node<_CharT>* __s) : base(__s) {} - - virtual ~__owns_one_state(); }; -template -__owns_one_state<_CharT>::~__owns_one_state() -{ - delete this->first(); -} - // __empty_state template @@ -1507,20 +1501,12 @@ explicit __owns_two_states(__node<_CharT>* __s1, base* __s2) : base(__s1), __second_(__s2) {} - virtual ~__owns_two_states(); - _LIBCPP_INLINE_VISIBILITY base* second() const {return __second_;} _LIBCPP_INLINE_VISIBILITY base*& second() {return __second_;} }; -template -__owns_two_states<_CharT>::~__owns_two_states() -{ - delete __second_; -} - // __loop template @@ -2493,17 +2479,51 @@ typedef typename _Traits::locale_type locale_type; private: + typedef _VSTD::__state<_CharT> __state; + typedef _VSTD::__node<_CharT> __node; + + // Shared, append-only storage for regexes. + class __storage + { + // invariant: __v_ is never nullptr. + shared_ptr>> __v_; + + public: + __storage() : __v_(make_shared>>()) {} + __storage(const __storage&) = default; + __storage(__storage&& __rhs) : __v_(std::move(__rhs.__v_)) + { __rhs.__clear(); } + + __storage& operator=(const __storage&) = default; + __storage& operator=(__storage&& __rhs) + { + __v_ = std::move(__rhs.__v_); + __rhs.__clear(); + return *this; + } + + __node* __push(__node* __n) + { + _LIBCPP_ASSERT(__v_.use_count() == 1, + "__push should be called only " + "when the storage is not shared"); + __v_->emplace_back(unique_ptr<__node>(__n)); + return __n; + } + + void __clear() + { __v_ = make_shared>>(); } + }; + _Traits __traits_; flag_type __flags_; unsigned __marked_count_; unsigned __loop_count_; int __open_count_; - shared_ptr<__empty_state<_CharT> > __start_; + __storage __storage_; + __empty_state<_CharT>* __start_; __owns_one_state<_CharT>* __end_; - typedef _VSTD::__state<_CharT> __state; - typedef _VSTD::__node<_CharT> __node; - public: // constants: static const regex_constants::syntax_option_type icase = regex_constants::icase; @@ -2521,17 +2541,17 @@ _LIBCPP_INLINE_VISIBILITY basic_regex() : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0), - __end_(0) + __start_(0), __end_(0) {} _LIBCPP_INLINE_VISIBILITY explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript) : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), - __end_(0) + __start_(0), __end_(0) {__parse(__p, __p + __traits_.length(__p));} _LIBCPP_INLINE_VISIBILITY basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript) : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), - __end_(0) + __start_(0), __end_(0) {__parse(__p, __p + __len);} // basic_regex(const basic_regex&) = default; // basic_regex(basic_regex&&) = default; @@ -2540,21 +2560,21 @@ explicit basic_regex(const basic_string& __p, flag_type __f = regex_constants::ECMAScript) : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), - __end_(0) + __start_(0), __end_(0) {__parse(__p.begin(), __p.end());} template _LIBCPP_INLINE_VISIBILITY basic_regex(_ForwardIterator __first, _ForwardIterator __last, flag_type __f = regex_constants::ECMAScript) : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), - __end_(0) + __start_(0), __end_(0) {__parse(__first, __last);} #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY basic_regex(initializer_list __il, flag_type __f = regex_constants::ECMAScript) : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), - __end_(0) + __start_(0), __end_(0) {__parse(__il.begin(), __il.end());} #endif // _LIBCPP_CXX03_LANG @@ -2656,7 +2676,8 @@ locale_type imbue(locale_type __loc) { __member_init(ECMAScript); - __start_.reset(); + __storage_.__clear(); + __start_ = nullptr; return __traits_.imbue(__loc); } _LIBCPP_INLINE_VISIBILITY @@ -2809,6 +2830,9 @@ __parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str = nullptr); + __node* __push(__node* __n) + { return __storage_.__push(__n); } + _LIBCPP_INLINE_VISIBILITY void __push_l_anchor(); void __push_r_anchor(); @@ -2953,6 +2977,7 @@ swap(__marked_count_, __r.__marked_count_); swap(__loop_count_, __r.__loop_count_); swap(__open_count_, __r.__open_count_); + swap(__storage_, __r.__storage_); swap(__start_, __r.__start_); swap(__end_, __r.__end_); } @@ -3023,10 +3048,10 @@ _ForwardIterator __last) { { - unique_ptr<__node> __h(new __end_state<_CharT>); - __start_.reset(new __empty_state<_CharT>(__h.get())); - __h.release(); - __end_ = __start_.get(); + __storage_.__clear(); + __start_ = new __empty_state<_CharT>(__push(new __end_state<_CharT>())); + __push(__start_); + __end_ = __start_; } switch (__flags_ & 0x1F0) { @@ -4618,16 +4643,17 @@ __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())); + __empty_state<_CharT>* __e1(new __empty_state<_CharT>(__end_->first())); + __push(__e1); __end_->first() = nullptr; - unique_ptr<__loop<_CharT> > __e2(new __loop<_CharT>(__loop_count_, - __s->first(), __e1.get(), __mexp_begin, __mexp_end, __greedy, + __loop<_CharT>* __e2(new __loop<_CharT>(__loop_count_, + __s->first(), __e1, __mexp_begin, __mexp_end, __greedy, __min, __max)); + __push(__e2); __s->first() = nullptr; - __e1.release(); - __end_->first() = new __repeat_one_loop<_CharT>(__e2.get()); + __end_->first() = __push(new __repeat_one_loop<_CharT>(__e2)); __end_ = __e2->second(); - __s->first() = __e2.release(); + __s->first() = __e2; ++__loop_count_; } @@ -4636,13 +4662,14 @@ basic_regex<_CharT, _Traits>::__push_char(value_type __c) { if (flags() & icase) - __end_->first() = new __match_char_icase<_CharT, _Traits> - (__traits_, __c, __end_->first()); + __end_->first() = __push(new __match_char_icase<_CharT, _Traits>( + __traits_, __c, __end_->first())); else if (flags() & collate) - __end_->first() = new __match_char_collate<_CharT, _Traits> - (__traits_, __c, __end_->first()); + __end_->first() = __push(new __match_char_collate<_CharT, _Traits>( + __traits_, __c, __end_->first())); else - __end_->first() = new __match_char<_CharT>(__c, __end_->first()); + __end_->first() = __push(new __match_char<_CharT>( + __c, __end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -4652,9 +4679,8 @@ { if (!(__flags_ & nosubs)) { - __end_->first() = - new __begin_marked_subexpression<_CharT>(++__marked_count_, - __end_->first()); + __end_->first() = __push(new __begin_marked_subexpression<_CharT>( + ++__marked_count_, __end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } } @@ -4665,8 +4691,8 @@ { if (!(__flags_ & nosubs)) { - __end_->first() = - new __end_marked_subexpression<_CharT>(__sub, __end_->first()); + __end_->first() = __push(new __end_marked_subexpression<_CharT>( + __sub, __end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } } @@ -4675,7 +4701,7 @@ void basic_regex<_CharT, _Traits>::__push_l_anchor() { - __end_->first() = new __l_anchor<_CharT>(__end_->first()); + __end_->first() = __push(new __l_anchor<_CharT>(__end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -4683,7 +4709,7 @@ void basic_regex<_CharT, _Traits>::__push_r_anchor() { - __end_->first() = new __r_anchor<_CharT>(__end_->first()); + __end_->first() = __push(new __r_anchor<_CharT>(__end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -4691,7 +4717,7 @@ void basic_regex<_CharT, _Traits>::__push_match_any() { - __end_->first() = new __match_any<_CharT>(__end_->first()); + __end_->first() = __push(new __match_any<_CharT>(__end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -4699,7 +4725,8 @@ void basic_regex<_CharT, _Traits>::__push_match_any_but_newline() { - __end_->first() = new __match_any_but_newline<_CharT>(__end_->first()); + __end_->first() = __push(new __match_any_but_newline<_CharT>( + __end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -4707,7 +4734,7 @@ void basic_regex<_CharT, _Traits>::__push_empty() { - __end_->first() = new __empty_state<_CharT>(__end_->first()); + __end_->first() = __push(new __empty_state<_CharT>(__end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -4715,8 +4742,8 @@ void basic_regex<_CharT, _Traits>::__push_word_boundary(bool __invert) { - __end_->first() = new __word_boundary<_CharT, _Traits>(__traits_, __invert, - __end_->first()); + __end_->first() = __push(new __word_boundary<_CharT, _Traits>( + __traits_, __invert, __end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -4725,13 +4752,13 @@ basic_regex<_CharT, _Traits>::__push_back_ref(int __i) { if (flags() & icase) - __end_->first() = new __back_ref_icase<_CharT, _Traits> - (__traits_, __i, __end_->first()); + __end_->first() = __push(new __back_ref_icase<_CharT, _Traits>( + __traits_, __i, __end_->first())); else if (flags() & collate) - __end_->first() = new __back_ref_collate<_CharT, _Traits> - (__traits_, __i, __end_->first()); + __end_->first() = __push(new __back_ref_collate<_CharT, _Traits>( + __traits_, __i, __end_->first())); else - __end_->first() = new __back_ref<_CharT>(__i, __end_->first()); + __end_->first() = __push(new __back_ref<_CharT>(__i, __end_->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -4740,13 +4767,13 @@ basic_regex<_CharT, _Traits>::__push_alternation(__owns_one_state<_CharT>* __sa, __owns_one_state<_CharT>* __ea) { - __sa->first() = new __alternate<_CharT>( + __sa->first() = __push(new __alternate<_CharT>( static_cast<__owns_one_state<_CharT>*>(__sa->first()), - static_cast<__owns_one_state<_CharT>*>(__ea->first())); + static_cast<__owns_one_state<_CharT>*>(__ea->first()))); __ea->first() = nullptr; - __ea->first() = new __empty_state<_CharT>(__end_->first()); + __ea->first() = __push(new __empty_state<_CharT>(__end_->first())); __end_->first() = nullptr; - __end_->first() = new __empty_non_own_state<_CharT>(__ea->first()); + __end_->first() = __push(new __empty_non_own_state<_CharT>(__ea->first())); __end_ = static_cast<__owns_one_state<_CharT>*>(__ea->first()); } @@ -4755,9 +4782,10 @@ basic_regex<_CharT, _Traits>::__start_matching_list(bool __negate) { __bracket_expression<_CharT, _Traits>* __r = - new __bracket_expression<_CharT, _Traits>(__traits_, __end_->first(), - __negate, __flags_ & icase, - __flags_ & collate); + new __bracket_expression<_CharT, _Traits>( + __traits_, __end_->first(), __negate, __flags_ & icase, + __flags_ & collate); + __push(__r); __end_->first() = __r; __end_ = __r; return __r; @@ -4769,8 +4797,8 @@ bool __invert, unsigned __mexp) { - __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert, - __end_->first(), __mexp); + __end_->first() = __push(new __lookahead<_CharT, _Traits>( + __exp, __invert, __end_->first(), __mexp)); __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first()); } @@ -5550,7 +5578,7 @@ regex_constants::match_flag_type __flags, bool __at_first) const { vector<__state> __states; - __node* __st = __start_.get(); + __node* __st = __start_; if (__st) { sub_match __unmatched; @@ -5636,7 +5664,7 @@ deque<__state> __states; ptrdiff_t __highest_j = 0; ptrdiff_t _Np = _VSTD::distance(__first, __last); - __node* __st = __start_.get(); + __node* __st = __start_; if (__st) { __states.push_back(__state()); @@ -5732,7 +5760,7 @@ ptrdiff_t __j = 0; ptrdiff_t __highest_j = 0; ptrdiff_t _Np = _VSTD::distance(__first, __last); - __node* __st = __start_.get(); + __node* __st = __start_; if (__st) { sub_match __unmatched;