timshen updated this revision to Diff 120334.
timshen added a comment.
Add an assertion to __push.
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,50 @@
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;
+ }
+
+ void __push(__node* __n)
+ {
+ _LIBCPP_ASSERT(__v_.use_count() == 1,
+ "__push should be called only "
+ "when the storage is not shared");
+ __v_->emplace_back(__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 +2540,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 +2675,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 +2829,9 @@
__parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last,
basic_string<_CharT>* __str = nullptr);
+ template <class _NodeType, class... _Args>
+ _NodeType* __push(_Args&&... __args);
+
_LIBCPP_INLINE_VISIBILITY
void __push_l_anchor();
void __push_r_anchor();
@@ -2953,6 +2976,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 +3047,9 @@
_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_ = __push<__empty_state<_CharT>>(__push<__end_state<_CharT>>());
+ __end_ = __start_;
}
switch (__flags_ & 0x1F0)
{
@@ -4612,37 +4635,45 @@
return __first;
}
+template <class _CharT, class _Traits>
+template <class _NodeType, class... _Args>
+_NodeType* basic_regex<_CharT, _Traits>::__push(_Args&&... __args)
+{
+ auto __ret = new _NodeType(std::forward<_Args>(__args)...);
+ __storage_.__push(__ret);
+ return __ret;
+}
+
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()));
+ __empty_state<_CharT>* __e1(__push<__empty_state<_CharT>>(__end_->first()));
__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(__push<__loop<_CharT>>(__loop_count_,
+ __s->first(), __e1, __mexp_begin, __mexp_end, __greedy,
__min, __max));
__s->first() = nullptr;
- __e1.release();
- __end_->first() = new __repeat_one_loop<_CharT>(__e2.get());
+ __end_->first() = __push<__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>
+ __end_->first() = __push<__match_char_icase<_CharT, _Traits>>
(__traits_, __c, __end_->first());
else if (flags() & collate)
- __end_->first() = new __match_char_collate<_CharT, _Traits>
+ __end_->first() = __push<__match_char_collate<_CharT, _Traits>>
(__traits_, __c, __end_->first());
else
- __end_->first() = new __match_char<_CharT>(__c, __end_->first());
+ __end_->first() = __push<__match_char<_CharT>>(__c, __end_->first());
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
}
@@ -4652,9 +4683,8 @@
{
if (!(__flags_ & nosubs))
{
- __end_->first() =
- new __begin_marked_subexpression<_CharT>(++__marked_count_,
- __end_->first());
+ __end_->first() = __push<__begin_marked_subexpression<_CharT>>(
+ ++__marked_count_, __end_->first());
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
}
}
@@ -4665,99 +4695,99 @@
{
if (!(__flags_ & nosubs))
{
- __end_->first() =
- new __end_marked_subexpression<_CharT>(__sub, __end_->first());
+ __end_->first() = __push<__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<__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<__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<__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<__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<__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<__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>
+ __end_->first() = __push<__back_ref_icase<_CharT, _Traits>>
(__traits_, __i, __end_->first());
else if (flags() & collate)
- __end_->first() = new __back_ref_collate<_CharT, _Traits>
+ __end_->first() = __push<__back_ref_collate<_CharT, _Traits>>
(__traits_, __i, __end_->first());
else
- __end_->first() = new __back_ref<_CharT>(__i, __end_->first());
+ __end_->first() = __push<__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<__alternate<_CharT>>(
static_cast<__owns_one_state<_CharT>*>(__sa->first()),
static_cast<__owns_one_state<_CharT>*>(__ea->first()));
__ea->first() = nullptr;
- __ea->first() = new __empty_state<_CharT>(__end_->first());
+ __ea->first() = __push<__empty_state<_CharT>>(__end_->first());
__end_->first() = nullptr;
- __end_->first() = new __empty_non_own_state<_CharT>(__ea->first());
+ __end_->first() = __push<__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);
+ __push<__bracket_expression<_CharT, _Traits>>(
+ __traits_, __end_->first(), __negate, __flags_ & icase,
+ __flags_ & collate);
__end_->first() = __r;
__end_ = __r;
return __r;
@@ -4769,8 +4799,8 @@
bool __invert,
unsigned __mexp)
{
- __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert,
- __end_->first(), __mexp);
+ __end_->first() = __push<__lookahead<_CharT, _Traits>>(
+ __exp, __invert, __end_->first(), __mexp);
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
}
@@ -5550,7 +5580,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 +5666,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 +5762,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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits