timshen updated this revision to Diff 120711. timshen added a comment. Remove the uses of variadic template and auto.
I'm not sure of how to implement this without a ABI change (the addition of __storage_). https://reviews.llvm.org/D39308 Files: libcxx/include/regex
Index: libcxx/include/regex =================================================================== --- libcxx/include/regex +++ libcxx/include/regex @@ -765,6 +765,8 @@ #include <vector> #include <deque> +#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 <class _CharT> -__owns_one_state<_CharT>::~__owns_one_state() -{ - delete this->first(); -} - // __empty_state template <class _CharT> @@ -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 <class _CharT> -__owns_two_states<_CharT>::~__owns_two_states() -{ - delete __second_; -} - // __loop template <class _CharT> @@ -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<vector<unique_ptr<__node>>> __v_; + + public: + __storage() : __v_(make_shared<vector<unique_ptr<__node>>>()) {} + __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<vector<unique_ptr<__node>>>(); } + }; + _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,40 +2541,40 @@ _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; template <class _ST, class _SA> _LIBCPP_INLINE_VISIBILITY explicit basic_regex(const basic_string<value_type, _ST, _SA>& __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 <class _ForwardIterator> _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<value_type> __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,31 +4643,33 @@ __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_; } template <class _CharT, class _Traits> void 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,99 +4691,101 @@ { 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()); } } template <class _CharT, class _Traits> 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()); } template <class _CharT, class _Traits> 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()); } template <class _CharT, class _Traits> 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()); } template <class _CharT, class _Traits> 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()); } template <class _CharT, class _Traits> 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()); } template <class _CharT, class _Traits> 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()); } template <class _CharT, class _Traits> void 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()); } template <class _CharT, class _Traits> void 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()); } template <class _CharT, class _Traits> __bracket_expression<_CharT, _Traits>* 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<const _CharT*> __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<const _CharT*> __unmatched;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits