{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT,
+ _RegexExecutorPolicy __policy,
+ bool __match_mode>
+ bool
+ __regex_algo_impl(_BiIter __s,
+ _BiIter __e,
+ match_results<_BiIter, _Alloc>& __m,
+ const basic_regex<_CharT, _TraitsT>& __re,
+ regex_constants::match_flag_type __flags);
+
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+
/**
* @addtogroup regex
* @{
/**
* @brief Class regex_traits. Describes aspects of a regular expression.
*
- * A regular expression traits class that satisfies the requirements of
+ * A regular expression traits class that satisfies the requirements of
* section [28.7].
*
* The class %regex is parameterized around a set of related types and
typedef _Ch_type char_type;
typedef std::basic_string<char_type> string_type;
typedef std::locale locale_type;
- typedef std::ctype_base::mask char_class_type;
+ private:
+ struct _RegexMask
+ {
+ typedef typename std::ctype<char_type>::mask _BaseType;
+ _BaseType _M_base;
+ unsigned char _M_extended;
+ static constexpr unsigned char _S_under = 1 << 0;
+ // FIXME: _S_blank should be removed in the future,
+ // when locale's complete.
+ static constexpr unsigned char _S_blank = 1 << 1;
+ static constexpr unsigned char _S_valid_mask = 0x3;
+
+ constexpr _RegexMask(_BaseType __base = 0,
+ unsigned char __extended = 0)
+ : _M_base(__base), _M_extended(__extended)
+ { }
+
+ constexpr _RegexMask
+ operator&(_RegexMask __other) const
+ {
+ return _RegexMask(_M_base & __other._M_base,
+ _M_extended & __other._M_extended);
+ }
+
+ constexpr _RegexMask
+ operator|(_RegexMask __other) const
+ {
+ return _RegexMask(_M_base | __other._M_base,
+ _M_extended | __other._M_extended);
+ }
+
+ constexpr _RegexMask
+ operator^(_RegexMask __other) const
+ {
+ return _RegexMask(_M_base ^ __other._M_base,
+ _M_extended ^ __other._M_extended);
+ }
+
+ constexpr _RegexMask
+ operator~() const
+ { return _RegexMask(~_M_base, ~_M_extended); }
+
+ _RegexMask&
+ operator&=(_RegexMask __other)
+ { return *this = (*this) & __other; }
+
+ _RegexMask&
+ operator|=(_RegexMask __other)
+ { return *this = (*this) | __other; }
+
+ _RegexMask&
+ operator^=(_RegexMask __other)
+ { return *this = (*this) ^ __other; }
+
+ constexpr bool
+ operator==(_RegexMask __other) const
+ {
+ return (_M_extended & _S_valid_mask)
+ == (__other._M_extended & _S_valid_mask)
+ && _M_base == __other._M_base;
+ }
+
+ constexpr bool
+ operator!=(_RegexMask __other) const
+ { return !((*this) == __other); }
+
+ };
+ public:
+ typedef _RegexMask char_class_type;
public:
/**
* @brief Constructs a default traits object.
*/
regex_traits() { }
-
+
/**
* @brief Gives the length of a C-style string starting at @p __p.
*
char_type
translate(char_type __c) const
{ return __c; }
-
+
/**
* @brief Translates a character into a case-insensitive equivalent.
*
*/
char_type
translate_nocase(char_type __c) const
- {
+ {
typedef std::ctype<char_type> __ctype_type;
const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
- return __fctyp.tolower(__c);
+ return __fctyp.tolower(__c);
}
-
+
/**
* @brief Gets a sort key for a character sequence.
*
* facet.
*/
template<typename _Fwd_iter>
- string_type
- transform(_Fwd_iter __first, _Fwd_iter __last) const
- {
+ string_type
+ transform(_Fwd_iter __first, _Fwd_iter __last) const
+ {
typedef std::collate<char_type> __collate_type;
const __collate_type& __fclt(use_facet<__collate_type>(_M_locale));
string_type __s(__first, __last);
*
* Effects: if typeid(use_facet<collate<_Ch_type> >) ==
* typeid(collate_byname<_Ch_type>) and the form of the sort key
- * returned by collate_byname<_Ch_type>::transform(__first, __last)
+ * returned by collate_byname<_Ch_type>::transform(__first, __last)
* is known and can be converted into a primary sort key
* then returns that key, otherwise returns an empty string.
*
- * @todo Implement this function.
+ * @todo Implement this function correctly.
*/
template<typename _Fwd_iter>
- string_type
- transform_primary(_Fwd_iter __first, _Fwd_iter __last) const
- { return string_type(); }
+ string_type
+ transform_primary(_Fwd_iter __first, _Fwd_iter __last) const
+ {
+ // TODO : this is not entirely correct.
+ // This function requires extra support from the platform.
+ //
+ // Read http://gcc.gnu.org/ml/libstdc++/2013-09/msg00117.html and
+ // http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2003/n1429.htm
+ // for details.
+ typedef std::ctype<char_type> __ctype_type;
+ const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
+ std::vector<char_type> __s(__first, __last);
+ __fctyp.tolower(__s.data(), __s.data() + __s.size());
+ return this->transform(__s.data(), __s.data() + __s.size());
+ }
/**
* @brief Gets a collation element by name.
*
* @param __first beginning of the collation element name.
* @param __last one-past-the-end of the collation element name.
- *
+ *
* @returns a sequence of one or more characters that represents the
* collating element consisting of the character sequence designated by
* the iterator range [__first, __last). Returns an empty string if the
* character sequence is not a valid collating element.
- *
- * @todo Implement this function.
*/
template<typename _Fwd_iter>
- string_type
- lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const
- { return string_type(); }
+ string_type
+ lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const;
/**
* @brief Maps one or more characters to a named character
* - space
* - upper
* - xdigit
- *
- * @todo Implement this function.
*/
template<typename _Fwd_iter>
- char_class_type
- lookup_classname(_Fwd_iter __first, _Fwd_iter __last,
- bool __icase = false) const
- { return 0; }
+ char_class_type
+ lookup_classname(_Fwd_iter __first, _Fwd_iter __last,
+ bool __icase = false) const;
/**
* @brief Determines if @p c is a member of an identified class.
* @param __ch a character representing a digit.
* @param __radix the radix if the numeric conversion (limited to 8, 10,
* or 16).
- *
+ *
* @returns the value represented by the digit __ch in base radix if the
* character __ch is a valid digit in base radix; otherwise returns -1.
*/
int
value(_Ch_type __ch, int __radix) const;
-
+
/**
* @brief Imbues the regex_traits object with a copy of a new locale.
*
std::swap(_M_locale, __loc);
return __loc;
}
-
+
/**
* @brief Gets a copy of the current locale in use by the regex_traits
* object.
locale_type
getloc() const
{ return _M_locale; }
-
+
protected:
locale_type _M_locale;
};
- template<typename _Ch_type>
- bool
- regex_traits<_Ch_type>::
- isctype(_Ch_type __c, char_class_type __f) const
- {
- typedef std::ctype<char_type> __ctype_type;
- const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-
- if (__fctyp.is(__f, __c))
- return true;
-
- // special case of underscore in [[:w:]]
- if (__c == __fctyp.widen('_'))
- {
- const char __wb[] = "w";
- char_class_type __wt = this->lookup_classname(__wb,
- __wb + sizeof(__wb));
- if (__f | __wt)
- return true;
- }
-
- // special case of [[:space:]] in [[:blank:]]
- if (__fctyp.is(std::ctype_base::space, __c))
- {
- const char __bb[] = "blank";
- char_class_type __bt = this->lookup_classname(__bb,
- __bb + sizeof(__bb));
- if (__f | __bt)
- return true;
- }
-
- return false;
- }
-
- template<typename _Ch_type>
- int
- regex_traits<_Ch_type>::
- value(_Ch_type __ch, int __radix) const
- {
- std::basic_istringstream<char_type> __is(string_type(1, __ch));
- int __v;
- if (__radix == 8)
- __is >> std::oct;
- else if (__radix == 16)
- __is >> std::hex;
- __is >> __v;
- return __is.fail() ? -1 : __v;
- }
-
// [7.8] Class basic_regex
/**
* Objects of specializations of this class represent regular expressions
* character sequence.
*/
basic_regex()
- : _M_flags(ECMAScript),
- _M_automaton(__detail::__compile<const _Ch_type*, _Rx_traits>(0, 0,
- _M_traits, _M_flags))
+ : _M_flags(ECMAScript), _M_automaton(nullptr)
{ }
/**
*/
explicit
basic_regex(const _Ch_type* __p, flag_type __f = ECMAScript)
- : _M_flags(__f),
- _M_automaton(__detail::__compile(__p, __p + _Rx_traits::length(__p),
- _M_traits, _M_flags))
+ : basic_regex(__p, __p + _Rx_traits::length(__p), __f)
{ }
/**
*
* @throws regex_error if @p __p is not a valid regular expression.
*/
- basic_regex(const _Ch_type* __p, std::size_t __len, flag_type __f)
- : _M_flags(__f),
- _M_automaton(__detail::__compile(__p, __p + __len, _M_traits, _M_flags))
+ basic_regex(const _Ch_type* __p, std::size_t __len,
+ flag_type __f = ECMAScript)
+ : basic_regex(__p, __p + __len, __f)
{ }
/**
*
* @param __rhs A @p regex object.
*/
- basic_regex(const basic_regex& __rhs)
- : _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits),
- _M_automaton(__rhs._M_automaton)
- { }
+ basic_regex(const basic_regex& __rhs) = default;
/**
* @brief Move-constructs a basic regular expression.
*/
basic_regex(const basic_regex&& __rhs) noexcept
: _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits),
- _M_automaton(std::move(__rhs._M_automaton))
+ _M_automaton(std::move(__rhs._M_automaton))
{ }
/**
* @throws regex_error if @p __s is not a valid regular expression.
*/
template<typename _Ch_traits, typename _Ch_alloc>
- explicit
- basic_regex(const std::basic_string<_Ch_type, _Ch_traits,
+ explicit
+ basic_regex(const std::basic_string<_Ch_type, _Ch_traits,
_Ch_alloc>& __s,
flag_type __f = ECMAScript)
- : _M_flags(__f),
- _M_automaton(__detail::__compile(__s.begin(), __s.end(),
- _M_traits, _M_flags))
- { }
+ : basic_regex(__s.begin(), __s.end(), __f)
+ { }
/**
* @brief Constructs a basic regular expression from the range
* @throws regex_error if @p [__first, __last) is not a valid regular
* expression.
*/
- template<typename _InputIterator>
- basic_regex(_InputIterator __first, _InputIterator __last,
+ template<typename _FwdIter>
+ basic_regex(_FwdIter __first, _FwdIter __last,
flag_type __f = ECMAScript)
: _M_flags(__f),
- _M_automaton(__detail::__compile(__first, __last, _M_traits, _M_flags))
- { }
+ _M_automaton(__detail::_Compiler<_FwdIter, _Ch_type, _Rx_traits>
+ (__first, __last, _M_traits, _M_flags)._M_get_nfa())
+ { }
/**
* @brief Constructs a basic regular expression from an initializer list.
*
* @throws regex_error if @p __l is not a valid regular expression.
*/
- basic_regex(initializer_list<_Ch_type> __l,
- flag_type __f = ECMAScript)
- : _M_flags(__f),
- _M_automaton(__detail::__compile(__l.begin(), __l.end(),
- _M_traits, _M_flags))
+ basic_regex(initializer_list<_Ch_type> __l, flag_type __f = ECMAScript)
+ : basic_regex(__l.begin(), __l.end(), __f)
{ }
/**
*/
~basic_regex()
{ }
-
+
/**
* @brief Assigns one regular expression to another.
*/
basic_regex&
operator=(const _Ch_type* __p)
{ return this->assign(__p, flags()); }
-
+
/**
* @brief Replaces a regular expression with a new one constructed from
* a string.
* @param __s A pointer to a string containing a regular expression.
*/
template<typename _Ch_typeraits, typename _Alloc>
- basic_regex&
- operator=(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s)
- { return this->assign(__s, flags()); }
+ basic_regex&
+ operator=(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s)
+ { return this->assign(__s, flags()); }
// [7.8.3] assign
/**
this->swap(__tmp);
return *this;
}
-
+
/**
* @brief The move-assignment operator.
*
{ return this->assign(string_type(__p, __len), __flags); }
/**
- * @brief Assigns a new regular expression to a regex object from a
+ * @brief Assigns a new regular expression to a regex object from a
* string containing a regular expression pattern.
*
* @param __s A string containing a regular expression pattern.
* regex_error is thrown, *this remains unchanged.
*/
template<typename _Ch_typeraits, typename _Alloc>
- basic_regex&
- assign(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s,
+ basic_regex&
+ assign(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s,
flag_type __flags = ECMAScript)
- {
- basic_regex __tmp(__s, __flags);
- this->swap(__tmp);
+ {
+ _M_flags = __flags;
+ _M_automaton =
+ __detail::_Compiler<decltype(__s.begin()), _Ch_type, _Rx_traits>
+ (__s.begin(), __s.end(), _M_traits, _M_flags)._M_get_nfa();
return *this;
}
* regex_error is thrown, the object remains unchanged.
*/
template<typename _InputIterator>
- basic_regex&
- assign(_InputIterator __first, _InputIterator __last,
+ basic_regex&
+ assign(_InputIterator __first, _InputIterator __last,
flag_type __flags = ECMAScript)
- { return this->assign(string_type(__first, __last), __flags); }
+ { return this->assign(string_type(__first, __last), __flags); }
/**
* @brief Assigns a new regular expression to a regex object.
unsigned int
mark_count() const
{ return _M_automaton->_M_sub_count() - 1; }
-
+
/**
* @brief Gets the flags used to construct the regular expression
* or in the last call to assign().
flag_type
flags() const
{ return _M_flags; }
-
+
// [7.8.5] locale
/**
* @brief Imbues the regular expression object with the given locale.
locale_type
imbue(locale_type __loc)
{ return _M_traits.imbue(__loc); }
-
+
/**
* @brief Gets the locale currently imbued in the regular expression
* object.
locale_type
getloc() const
{ return _M_traits.getloc(); }
-
+
// [7.8.6] swap
/**
* @brief Swaps the contents of two regular expression objects.
_M_dot(std::ostream& __ostr)
{ _M_automaton->_M_dot(__ostr); }
#endif
-
- const __detail::_AutomatonPtr&
- _M_get_automaton() const
- { return _M_automaton; }
protected:
- flag_type _M_flags;
- _Rx_traits _M_traits;
- __detail::_AutomatonPtr _M_automaton;
+ typedef std::shared_ptr<__detail::_Automaton<_Ch_type, _Rx_traits>>
+ _AutomatonPtr;
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT,
+ __detail::_RegexExecutorPolicy __policy>
+ friend std::unique_ptr<
+ __detail::_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+ __detail::__get_executor(_BiIter,
+ _BiIter,
+ std::vector<sub_match<_BiIter>, _Alloc>&,
+ const basic_regex<_CharT, _TraitsT>&,
+ regex_constants::match_flag_type);
+
+ template<typename _Bp, typename _Ap, typename _Cp, typename _Rp,
+ __detail::_RegexExecutorPolicy, bool>
+ friend bool
+ __detail::__regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&,
+ const basic_regex<_Cp, _Rp>&,
+ regex_constants::match_flag_type);
+
+ template<typename, typename, typename, typename>
+ friend class __detail::_Executor;
+
+ template<typename, typename, typename, typename>
+ friend class __detail::_DFSExecutor;
+
+ template<typename, typename, typename, typename>
+ friend class __detail::_BFSExecutor;
+
+ flag_type _M_flags;
+ _Rx_traits _M_traits;
+ _AutomatonPtr _M_automaton;
};
-
+
/** @brief Standard regular expressions. */
typedef basic_regex<char> regex;
typedef std::basic_string<value_type> string_type;
bool matched;
-
+
constexpr sub_match() : matched() { }
/**
? string_type(this->first, this->second)
: string_type();
}
-
+
/**
* @brief Gets the matching sequence as a string.
*
? string_type(this->first, this->second)
: string_type();
}
-
+
/**
* @brief Compares this and another matched sequence.
*
int
compare(const string_type& __s) const
{ return this->str().compare(__s); }
-
+
/**
* @brief Compares this sub_match to a C-style string.
*
compare(const value_type* __s) const
{ return this->str().compare(__s); }
};
-
-
+
+
/** @brief Standard regex submatch over a C-style null-terminated string. */
typedef sub_match<const char*> csub_match;
#endif
// [7.9.2] sub_match non-member operators
-
+
/**
* @brief Tests the equivalence of two regular expression submatches.
* @param __lhs First regular expression submatch.
// Alias for sub_match'd string.
template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
using __sub_match_string = basic_string<
- typename iterator_traits<_Bi_iter>::value_type,
- _Ch_traits, _Ch_alloc>;
+ typename iterator_traits<_Bi_iter>::value_type,
+ _Ch_traits, _Ch_alloc>;
/**
* @brief Tests the equivalence of a string and a regular expression
* @name 10.? Public Types
*/
//@{
- typedef _Alloc allocator_type;
typedef sub_match<_Bi_iter> value_type;
typedef const value_type& const_reference;
typedef const_reference reference;
typedef typename _Base_type::const_iterator const_iterator;
typedef const_iterator iterator;
typedef typename __iter_traits::difference_type difference_type;
- typedef typename __iter_traits::value_type char_type;
typedef typename allocator_traits<_Alloc>::size_type size_type;
-
-
+ typedef _Alloc allocator_type;
+ typedef typename __iter_traits::value_type char_type;
typedef std::basic_string<char_type> string_type;
//@}
-
+
public:
/**
* @name 28.10.1 Construction, Copying, and Destruction
*/
explicit
match_results(const _Alloc& __a = _Alloc())
- : _Base_type(__a)
+ : _Base_type(__a), _M_in_iterator(false)
{ }
/**
* @brief Copy constructs a %match_results.
*/
match_results(const match_results& __rhs)
- : _Base_type(__rhs)
+ : _Base_type(__rhs), _M_in_iterator(false)
{ }
/**
* @brief Move constructs a %match_results.
*/
match_results(match_results&& __rhs) noexcept
- : _Base_type(std::move(__rhs))
+ : _Base_type(std::move(__rhs)), _M_in_iterator(false)
{ }
/**
*/
~match_results()
{ }
-
+
//@}
// 28.10.2, state:
size_type __size = _Base_type::size();
return (__size && _Base_type::operator[](0).matched) ? __size - 2 : 0;
}
-
+
size_type
max_size() const
{ return _Base_type::max_size(); }
bool
empty() const
{ return size() == 0; }
-
+
//@}
/**
difference_type
position(size_type __sub = 0) const
{
- return __sub < size() ? std::distance(this->prefix().first,
- (*this)[__sub].first) : -1;
+ // [28.12.1.4.5]
+ if (_M_in_iterator)
+ return __sub < size() ? std::distance(_M_begin,
+ (*this)[__sub].first) : -1;
+ else
+ return __sub < size() ? std::distance(this->prefix().first,
+ (*this)[__sub].first) : -1;
}
/**
string_type
str(size_type __sub = 0) const
{ return (*this)[__sub].str(); }
-
+
/**
* @brief Gets a %sub_match reference for the match or submatch.
* @param __sub indicates the submatch.
*/
const_reference
operator[](size_type __sub) const
- {
+ {
_GLIBCXX_DEBUG_ASSERT( ready() );
return __sub < size()
? _Base_type::operator[](__sub)
const_iterator
begin() const
{ return _Base_type::begin(); }
-
+
/**
* @brief Gets an iterator to the start of the %sub_match collection.
*/
const_iterator
cbegin() const
- { return _Base_type::cbegin(); }
+ { return _Base_type::cbegin() + 2; }
/**
* @brief Gets an iterator to one-past-the-end of the collection.
*/
const_iterator
end() const
- { return !empty() ? _Base_type::end() - 2 : _Base_type::end(); }
-
+ { return _Base_type::end() - 2; }
+
/**
* @brief Gets an iterator to one-past-the-end of the collection.
*/
const_iterator
cend() const
- { return end(); }
+ { return _Base_type::cend(); }
//@}
/**
* @pre ready() == true
- * @todo Implement this function.
*/
template<typename _Out_iter>
- _Out_iter
- format(_Out_iter __out, const char_type* __fmt_first,
+ _Out_iter
+ format(_Out_iter __out, const char_type* __fmt_first,
const char_type* __fmt_last,
- match_flag_type __flags = regex_constants::format_default) const
- { return __out; }
+ match_flag_type __flags = regex_constants::format_default) const;
/**
* @pre ready() == true
*/
template<typename _Out_iter, typename _St, typename _Sa>
- _Out_iter
- format(_Out_iter __out, const basic_string<char_type, _St, _Sa>& __fmt,
+ _Out_iter
+ format(_Out_iter __out, const basic_string<char_type, _St, _Sa>& __fmt,
match_flag_type __flags = regex_constants::format_default) const
- {
- return format(__out, __fmt.data(), __fmt.data() + __fmt.size(),
- __flags);
- }
+ {
+ return format(__out, __fmt.data(), __fmt.data() + __fmt.size(),
+ __flags);
+ }
/**
* @pre ready() == true
*/
template<typename _Out_iter, typename _St, typename _Sa>
- basic_string<char_type, _St, _Sa>
- format(const basic_string<char_type, _St, _Sa>& __fmt,
+ basic_string<char_type, _St, _Sa>
+ format(const basic_string<char_type, _St, _Sa>& __fmt,
match_flag_type __flags = regex_constants::format_default) const
- {
- basic_string<char_type, _St, _Sa> __result;
- format(std::back_inserter(__result), __fmt, __flags);
- return __result;
- }
+ {
+ basic_string<char_type, _St, _Sa> __result;
+ format(std::back_inserter(__result), __fmt, __flags);
+ return __result;
+ }
/**
* @pre ready() == true
format(const char_type* __fmt,
match_flag_type __flags = regex_constants::format_default) const
{
- string_type __result;
- format(std::back_inserter(__result),
- __fmt + char_traits<char_type>::length(__fmt),
- __flags);
- return __result;
+ string_type __result;
+ format(std::back_inserter(__result),
+ __fmt,
+ __fmt + char_traits<char_type>::length(__fmt),
+ __flags);
+ return __result;
}
- //@}
+ //@}
/**
* @name 10.5 Allocator
*/
- //@{
+ //@{
/**
* @brief Gets a copy of the allocator.
allocator_type
get_allocator() const
{ return _Base_type::get_allocator(); }
-
- //@}
+
+ //@}
/**
* @name 10.6 Swap
*/
- //@{
+ //@{
/**
* @brief Swaps the contents of two match_results.
void
swap(match_results& __that)
{ _Base_type::swap(__that); }
- //@}
-
+ //@}
+
private:
- friend class __detail::_SpecializedResults<_Bi_iter, _Alloc>;
+ template<typename, typename, typename, typename>
+ friend class __detail::_Executor;
+
+ template<typename, typename, typename, typename>
+ friend class __detail::_DFSExecutor;
+
+ template<typename, typename, typename, typename>
+ friend class __detail::_BFSExecutor;
+
+ template<typename, typename, typename>
+ friend class regex_iterator;
+
+ template<typename _Bp, typename _Ap, typename _Cp, typename _Rp,
+ __detail::_RegexExecutorPolicy, bool>
+ friend bool
+ __detail::__regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&,
+ const basic_regex<_Cp, _Rp>&,
+ regex_constants::match_flag_type);
+
+ _Bi_iter _M_begin;
+ bool _M_in_iterator;
};
-
+
typedef match_results<const char*> cmatch;
typedef match_results<string::const_iterator> smatch;
#ifdef _GLIBCXX_USE_WCHAR_T
const match_results<_Bi_iter, _Alloc>& __m2)
{
if (__m1.ready() != __m2.ready())
- return false;
+ return false;
if (!__m1.ready()) // both are not ready
- return true;
+ return true;
if (__m1.empty() != __m2.empty())
- return false;
+ return false;
if (__m1.empty()) // both are empty
- return true;
+ return true;
return __m1.prefix() == __m2.prefix()
- && __m1.size() == __m2.size()
- && std::equal(__m1.begin(), __m1.end(), __m2.begin())
- && __m1.suffix() == __m2.suffix();
+ && __m1.size() == __m2.size()
+ && std::equal(__m1.begin(), __m1.end(), __m2.begin())
+ && __m1.suffix() == __m2.suffix();
}
/**
* @retval false Otherwise.
*
* @throws an exception of type regex_error.
- *
- * @todo Implement this function.
*/
template<typename _Bi_iter, typename _Alloc,
typename _Ch_type, typename _Rx_traits>
- bool
+ inline bool
regex_match(_Bi_iter __s,
- _Bi_iter __e,
- match_results<_Bi_iter, _Alloc>& __m,
- const basic_regex<_Ch_type, _Rx_traits>& __re,
- regex_constants::match_flag_type __flags
- = regex_constants::match_default)
+ _Bi_iter __e,
+ match_results<_Bi_iter, _Alloc>& __m,
+ const basic_regex<_Ch_type, _Rx_traits>& __re,
+ regex_constants::match_flag_type __flags
+ = regex_constants::match_default)
{
- __detail::_AutomatonPtr __a = __re._M_get_automaton();
- __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
- __detail::_SpecializedCursor<_Bi_iter> __cs(__s, __e);
- __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
- __detail::_Grep_matcher __matcher(__cs, __r, __a, __flags);
- return __m[0].matched;
+ return __detail::__regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits,
+ __detail::_RegexExecutorPolicy::_S_auto, true>
+ (__s, __e, __m, __re, __flags);
}
/**
* @throws an exception of type regex_error.
*/
template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
- bool
+ inline bool
regex_match(_Bi_iter __first, _Bi_iter __last,
const basic_regex<_Ch_type, _Rx_traits>& __re,
regex_constants::match_flag_type __flags
= regex_constants::match_default)
- {
+ {
match_results<_Bi_iter> __what;
return regex_match(__first, __last, __what, __re, __flags);
}
typename _Alloc, typename _Ch_type, typename _Rx_traits>
inline bool
regex_match(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s,
- match_results<typename basic_string<_Ch_type,
+ match_results<typename basic_string<_Ch_type,
_Ch_traits, _Ch_alloc>::const_iterator, _Alloc>& __m,
const basic_regex<_Ch_type, _Rx_traits>& __re,
regex_constants::match_flag_type __flags
* undefined.
*
* @throws an exception of type regex_error.
- *
- * @todo Implement this function.
*/
template<typename _Bi_iter, typename _Alloc,
typename _Ch_type, typename _Rx_traits>
inline bool
- regex_search(_Bi_iter __first, _Bi_iter __last,
+ regex_search(_Bi_iter __s, _Bi_iter __e,
match_results<_Bi_iter, _Alloc>& __m,
const basic_regex<_Ch_type, _Rx_traits>& __re,
regex_constants::match_flag_type __flags
= regex_constants::match_default)
- { return false; }
+ {
+ return __detail::__regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits,
+ __detail::_RegexExecutorPolicy::_S_auto, false>
+ (__s, __e, __m, __re, __flags);
+ }
/**
* Searches for a regular expression within a range.
* @param __flags [IN] Search policy flags.
* @retval true A match was found within the string.
* @retval false No match was found within the string.
- * @doctodo
*
* @throws an exception of type regex_error.
*/
* @retval true A match was found within the string.
* @retval false No match was found within the string, the content of %m is
* undefined.
- * @doctodo
*
* @throws an exception of type regex_error.
*/
* @param __f [IN] Search policy flags.
* @retval true A match was found within the string.
* @retval false No match was found within the string.
- * @doctodo
*
* @throws an exception of type regex_error.
*/
* @param __flags [IN] Search policy flags.
* @retval true A match was found within the string.
* @retval false No match was found within the string.
- * @doctodo
*
* @throws an exception of type regex_error.
*/
// std [28.11.4] Function template regex_replace
/**
- * @doctodo
- * @param __out
- * @param __first
- * @param __last
- * @param __e
- * @param __fmt
- * @param __flags
+ * @brief Search for a regular expression within a range for multiple times,
+ and replace the matched parts through filling a format string.
+ * @param __out [OUT] The output iterator.
+ * @param __first [IN] The start of the string to search.
+ * @param __last [IN] One-past-the-end of the string to search.
+ * @param __e [IN] The regular expression to search for.
+ * @param __fmt [IN] The format string.
+ * @param __flags [IN] Search and replace policy flags.
*
- * @returns out
+ * @returns __out
* @throws an exception of type regex_error.
+ */
+ template<typename _Out_iter, typename _Bi_iter,
+ typename _Rx_traits, typename _Ch_type,
+ typename _St, typename _Sa>
+ inline _Out_iter
+ regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
+ const basic_regex<_Ch_type, _Rx_traits>& __e,
+ const basic_string<_Ch_type, _St, _Sa>& __fmt,
+ regex_constants::match_flag_type __flags
+ = regex_constants::match_default)
+ {
+ return regex_replace(__out, __first, __last, __e, __fmt.c_str(), __flags);
+ }
+
+ /**
+ * @brief Search for a regular expression within a range for multiple times,
+ and replace the matched parts through filling a format C-string.
+ * @param __out [OUT] The output iterator.
+ * @param __first [IN] The start of the string to search.
+ * @param __last [IN] One-past-the-end of the string to search.
+ * @param __e [IN] The regular expression to search for.
+ * @param __fmt [IN] The format C-string.
+ * @param __flags [IN] Search and replace policy flags.
*
- * @todo Implement this function.
+ * @returns __out
+ * @throws an exception of type regex_error.
*/
template<typename _Out_iter, typename _Bi_iter,
typename _Rx_traits, typename _Ch_type>
- inline _Out_iter
+ _Out_iter
regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
const basic_regex<_Ch_type, _Rx_traits>& __e,
- const basic_string<_Ch_type>& __fmt,
+ const _Ch_type* __fmt,
+ regex_constants::match_flag_type __flags
+ = regex_constants::match_default);
+
+ /**
+ * @brief Search for a regular expression within a string for multiple times,
+ and replace the matched parts through filling a format string.
+ * @param __s [IN] The string to search and replace.
+ * @param __e [IN] The regular expression to search for.
+ * @param __fmt [IN] The format string.
+ * @param __flags [IN] Search and replace policy flags.
+ *
+ * @returns The string after replacing.
+ * @throws an exception of type regex_error.
+ */
+ template<typename _Rx_traits, typename _Ch_type,
+ typename _St, typename _Sa, typename _Fst, typename _Fsa>
+ inline basic_string<_Ch_type, _St, _Sa>
+ regex_replace(const basic_string<_Ch_type, _St, _Sa>& __s,
+ const basic_regex<_Ch_type, _Rx_traits>& __e,
+ const basic_string<_Ch_type, _Fst, _Fsa>& __fmt,
+ regex_constants::match_flag_type __flags
+ = regex_constants::match_default)
+ {
+ basic_string<_Ch_type, _St, _Sa> __result;
+ regex_replace(std::back_inserter(__result),
+ __s.begin(), __s.end(), __e, __fmt, __flags);
+ return __result;
+ }
+
+ /**
+ * @brief Search for a regular expression within a string for multiple times,
+ and replace the matched parts through filling a format C-string.
+ * @param __s [IN] The string to search and replace.
+ * @param __e [IN] The regular expression to search for.
+ * @param __fmt [IN] The format C-string.
+ * @param __flags [IN] Search and replace policy flags.
+ *
+ * @returns The string after replacing.
+ * @throws an exception of type regex_error.
+ */
+ template<typename _Rx_traits, typename _Ch_type,
+ typename _St, typename _Sa>
+ inline basic_string<_Ch_type, _St, _Sa>
+ regex_replace(const basic_string<_Ch_type, _St, _Sa>& __s,
+ const basic_regex<_Ch_type, _Rx_traits>& __e,
+ const _Ch_type* __fmt,
regex_constants::match_flag_type __flags
= regex_constants::match_default)
- { return __out; }
+ {
+ basic_string<_Ch_type, _St, _Sa> __result;
+ regex_replace(std::back_inserter(__result),
+ __s.begin(), __s.end(), __e, __fmt, __flags);
+ return __result;
+ }
/**
- * @doctodo
- * @param __s
- * @param __e
- * @param __fmt
- * @param __flags
+ * @brief Search for a regular expression within a C-string for multiple
+ times, and replace the matched parts through filling a format string.
+ * @param __s [IN] The C-string to search and replace.
+ * @param __e [IN] The regular expression to search for.
+ * @param __fmt [IN] The format string.
+ * @param __flags [IN] Search and replace policy flags.
*
- * @returns a copy of string @p s with replacements.
+ * @returns The string after replacing.
+ * @throws an exception of type regex_error.
+ */
+ template<typename _Rx_traits, typename _Ch_type,
+ typename _St, typename _Sa>
+ inline basic_string<_Ch_type>
+ regex_replace(const _Ch_type* __s,
+ const basic_regex<_Ch_type, _Rx_traits>& __e,
+ const basic_string<_Ch_type, _St, _Sa>& __fmt,
+ regex_constants::match_flag_type __flags
+ = regex_constants::match_default)
+ {
+ basic_string<_Ch_type> __result;
+ regex_replace(std::back_inserter(__result), __s,
+ __s + char_traits<_Ch_type>::length(__s),
+ __e, __fmt, __flags);
+ return __result;
+ }
+
+ /**
+ * @brief Search for a regular expression within a C-string for multiple
+ times, and replace the matched parts through filling a format C-string.
+ * @param __s [IN] The C-string to search and replace.
+ * @param __e [IN] The regular expression to search for.
+ * @param __fmt [IN] The format C-string.
+ * @param __flags [IN] Search and replace policy flags.
*
+ * @returns The string after replacing.
* @throws an exception of type regex_error.
*/
template<typename _Rx_traits, typename _Ch_type>
inline basic_string<_Ch_type>
- regex_replace(const basic_string<_Ch_type>& __s,
+ regex_replace(const _Ch_type* __s,
const basic_regex<_Ch_type, _Rx_traits>& __e,
- const basic_string<_Ch_type>& __fmt,
+ const _Ch_type* __fmt,
regex_constants::match_flag_type __flags
= regex_constants::match_default)
{
basic_string<_Ch_type> __result;
- regex_replace(std::back_inserter(__result),
- __s.begin(), __s.end(), __e, __fmt, __flags);
+ regex_replace(std::back_inserter(__result), __s,
+ __s + char_traits<_Ch_type>::length(__s),
+ __e, __fmt, __flags);
return __result;
}
// std [28.12] Class template regex_iterator
/**
- * An iterator adaptor that will provide repeated calls of regex_search over
+ * An iterator adaptor that will provide repeated calls of regex_search over
* a range until no more matches remain.
*/
template<typename _Bi_iter,
/**
* @brief Provides a singular iterator, useful for indicating
* one-past-the-end of a range.
- * @todo Implement this function.
- * @doctodo
*/
- regex_iterator();
-
+ regex_iterator()
+ : _M_match()
+ { }
+
/**
* Constructs a %regex_iterator...
* @param __a [IN] The start of a text range to search.
* @param __b [IN] One-past-the-end of the text range to search.
* @param __re [IN] The regular expression to match.
* @param __m [IN] Policy flags for match rules.
- * @todo Implement this function.
- * @doctodo
*/
regex_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re,
regex_constants::match_flag_type __m
- = regex_constants::match_default);
+ = regex_constants::match_default)
+ : _M_begin(__a), _M_end(__b), _M_pregex(&__re), _M_flags(__m), _M_match()
+ {
+ if (!regex_search(_M_begin, _M_end, _M_match, *_M_pregex, _M_flags))
+ *this = regex_iterator();
+ }
/**
* Copy constructs a %regex_iterator.
- * @todo Implement this function.
- * @doctodo
*/
- regex_iterator(const regex_iterator& __rhs);
-
+ regex_iterator(const regex_iterator& __rhs) = default;
+
/**
- * @todo Implement this function.
- * @doctodo
+ * @brief Assigns one %regex_iterator to another.
*/
regex_iterator&
- operator=(const regex_iterator& __rhs);
-
+ operator=(const regex_iterator& __rhs) = default;
+
/**
- * @todo Implement this function.
- * @doctodo
+ * @brief Tests the equivalence of two regex iterators.
*/
bool
- operator==(const regex_iterator& __rhs);
-
+ operator==(const regex_iterator& __rhs) const;
+
/**
- * @todo Implement this function.
- * @doctodo
+ * @brief Tests the inequivalence of two regex iterators.
*/
bool
- operator!=(const regex_iterator& __rhs);
-
+ operator!=(const regex_iterator& __rhs) const
+ { return !(*this == __rhs); }
+
/**
- * @todo Implement this function.
- * @doctodo
+ * @brief Dereferences a %regex_iterator.
*/
const value_type&
- operator*();
-
+ operator*() const
+ { return _M_match; }
+
/**
- * @todo Implement this function.
- * @doctodo
+ * @brief Selects a %regex_iterator member.
*/
const value_type*
- operator->();
-
+ operator->() const
+ { return &_M_match; }
+
/**
- * @todo Implement this function.
- * @doctodo
+ * @brief Increments a %regex_iterator.
*/
regex_iterator&
operator++();
-
+
/**
- * @todo Implement this function.
- * @doctodo
+ * @brief Postincrements a %regex_iterator.
*/
regex_iterator
- operator++(int);
-
+ operator++(int)
+ {
+ auto __tmp = *this;
+ ++(*this);
+ return __tmp;
+ }
+
private:
- // these members are shown for exposition only:
- _Bi_iter begin;
- _Bi_iter end;
- const regex_type* pregex;
- regex_constants::match_flag_type flags;
- match_results<_Bi_iter> match;
+ _Bi_iter _M_begin;
+ _Bi_iter _M_end;
+ const regex_type* _M_pregex;
+ regex_constants::match_flag_type _M_flags;
+ match_results<_Bi_iter> _M_match;
};
-
+
typedef regex_iterator<const char*> cregex_iterator;
typedef regex_iterator<string::const_iterator> sregex_iterator;
#ifdef _GLIBCXX_USE_WCHAR_T
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
-
+
public:
/**
* @brief Default constructs a %regex_token_iterator.
- * @todo Implement this function.
- *
+ *
* A default-constructed %regex_token_iterator is a singular iterator
* that will compare equal to the one-past-the-end value for any
* iterator of the same type.
*/
- regex_token_iterator();
-
+ regex_token_iterator()
+ : _M_position(), _M_subs(), _M_suffix(), _M_n(0), _M_result(nullptr),
+ _M_has_m1(false)
+ { }
+
/**
* Constructs a %regex_token_iterator...
* @param __a [IN] The start of the text to search.
* - >0 enumerates only the indicated
* subexpression from a match within the text.
* @param __m [IN] Policy flags for match rules.
- *
- * @todo Implement this function.
- * @doctodo
*/
regex_token_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re,
int __submatch = 0,
regex_constants::match_flag_type __m
- = regex_constants::match_default);
+ = regex_constants::match_default)
+ : _M_position(__a, __b, __re, __m), _M_subs(1, __submatch), _M_n(0)
+ { _M_init(__a, __b); }
/**
* Constructs a %regex_token_iterator...
* @param __b [IN] One-past-the-end of the text to search.
* @param __re [IN] The regular expression to search for.
* @param __submatches [IN] A list of subexpressions to return for each
- * regular expression match within the text.
+ * regular expression match within the text.
* @param __m [IN] Policy flags for match rules.
- *
- * @todo Implement this function.
- * @doctodo
*/
regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
const regex_type& __re,
const std::vector<int>& __submatches,
regex_constants::match_flag_type __m
- = regex_constants::match_default);
+ = regex_constants::match_default)
+ : _M_position(__a, __b, __re, __m), _M_subs(__submatches), _M_n(0)
+ { _M_init(__a, __b); }
+
+ /**
+ * Constructs a %regex_token_iterator...
+ * @param __a [IN] The start of the text to search.
+ * @param __b [IN] One-past-the-end of the text to search.
+ * @param __re [IN] The regular expression to search for.
+ * @param __submatches [IN] A list of subexpressions to return for each
+ * regular expression match within the text.
+ * @param __m [IN] Policy flags for match rules.
+ */
+ regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
+ const regex_type& __re,
+ initializer_list<int> __submatches,
+ regex_constants::match_flag_type __m
+ = regex_constants::match_default)
+ : _M_position(__a, __b, __re, __m), _M_subs(__submatches), _M_n(0)
+ { _M_init(__a, __b); }
/**
* Constructs a %regex_token_iterator...
* @param __submatches [IN] A list of subexpressions to return for each
* regular expression match within the text.
* @param __m [IN] Policy flags for match rules.
-
- * @todo Implement this function.
- * @doctodo
*/
template<std::size_t _Nm>
- regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
+ regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
const regex_type& __re,
const int (&__submatches)[_Nm],
regex_constants::match_flag_type __m
- = regex_constants::match_default);
+ = regex_constants::match_default)
+ : _M_position(__a, __b, __re, __m),
+ _M_subs(__submatches, *(&__submatches+1)), _M_n(0)
+ { _M_init(__a, __b); }
/**
* @brief Copy constructs a %regex_token_iterator.
* @param __rhs [IN] A %regex_token_iterator to copy.
- * @todo Implement this function.
*/
- regex_token_iterator(const regex_token_iterator& __rhs);
-
+ regex_token_iterator(const regex_token_iterator& __rhs)
+ : _M_position(__rhs._M_position), _M_subs(__rhs._M_subs),
+ _M_suffix(__rhs._M_suffix), _M_n(__rhs._M_n), _M_result(__rhs._M_result),
+ _M_has_m1(__rhs._M_has_m1)
+ {
+ if (__rhs._M_result == &__rhs._M_suffix)
+ _M_result = &_M_suffix;
+ }
+
/**
* @brief Assigns a %regex_token_iterator to another.
* @param __rhs [IN] A %regex_token_iterator to copy.
- * @todo Implement this function.
*/
regex_token_iterator&
operator=(const regex_token_iterator& __rhs);
-
+
/**
* @brief Compares a %regex_token_iterator to another for equality.
- * @todo Implement this function.
*/
bool
- operator==(const regex_token_iterator& __rhs);
-
+ operator==(const regex_token_iterator& __rhs) const;
+
/**
* @brief Compares a %regex_token_iterator to another for inequality.
- * @todo Implement this function.
*/
bool
- operator!=(const regex_token_iterator& __rhs);
-
+ operator!=(const regex_token_iterator& __rhs) const
+ { return !(*this == __rhs); }
+
/**
* @brief Dereferences a %regex_token_iterator.
- * @todo Implement this function.
*/
const value_type&
- operator*();
-
+ operator*() const
+ { return *_M_result; }
+
/**
* @brief Selects a %regex_token_iterator member.
- * @todo Implement this function.
*/
const value_type*
- operator->();
-
+ operator->() const
+ { return _M_result; }
+
/**
* @brief Increments a %regex_token_iterator.
- * @todo Implement this function.
*/
regex_token_iterator&
operator++();
-
+
/**
* @brief Postincrements a %regex_token_iterator.
- * @todo Implement this function.
*/
regex_token_iterator
- operator++(int);
-
- private: // data members for exposition only:
- typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> position_iterator;
-
- position_iterator __position;
- const value_type* __result;
- value_type __suffix;
- std::size_t __n;
- std::vector<int> __subs;
+ operator++(int)
+ {
+ auto __tmp = *this;
+ ++(*this);
+ return __tmp;
+ }
+
+ private:
+ typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _Position;
+
+ void
+ _M_init(_Bi_iter __a, _Bi_iter __b);
+
+ const value_type&
+ _M_current_match() const
+ {
+ if (_M_subs[_M_n] == -1)
+ return (*_M_position).prefix();
+ else
+ return (*_M_position)[_M_subs[_M_n]];
+ }
+
+ constexpr bool
+ _M_end_of_seq()
+ { return _M_result == nullptr; }
+
+ _Position _M_position;
+ std::vector<int> _M_subs;
+ value_type _M_suffix;
+ std::size_t _M_n;
+ const value_type* _M_result;
+
+ // Show whether _M_subs contains -1
+ bool _M_has_m1;
};
/** @brief Token iterator for C-style NULL-terminated strings. */
/** @brief Token iterator for standard wide-character strings. */
typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
#endif
-
+
//@} // group regex
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
+#include <bits/regex.tcc>