From 5a6ea019fd48b269121f95dc4afabce760531bbe Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 9 May 2012 11:49:37 +0200 Subject: Make regex class template --- cutl/re/re.cxx | 202 +++++++++++++++++++++++++++++++++------------------------ cutl/re/re.txx | 69 ++++++++++++++++++++ 2 files changed, 188 insertions(+), 83 deletions(-) create mode 100644 cutl/re/re.txx (limited to 'cutl/re') diff --git a/cutl/re/re.cxx b/cutl/re/re.cxx index 8a15158..8e46d59 100644 --- a/cutl/re/re.cxx +++ b/cutl/re/re.cxx @@ -2,8 +2,6 @@ // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file -#include - #include #ifndef LIBCUTL_EXTERNAL_BOOST @@ -19,53 +17,83 @@ namespace cutl namespace re { // - // format + // format_base // - format:: - ~format () throw () + format_base:: + ~format_base () throw () { } - char const* format:: + char const* format_base:: what () const throw () { return description_.c_str (); } // - // regex + // basic_regex // - struct regex::impl + template + struct basic_regex::impl { + typedef basic_string string_type; + typedef tr1::basic_regex regex_type; + impl () {} - impl (string const& s): r (s, tr1::regex_constants::ECMAScript) {} - impl (tr1::regex const& r): r (r) {} + impl (string_type const& s): r (s, tr1::regex_constants::ECMAScript) {} + impl (regex_type const& r): r (r) {} - tr1::regex r; + regex_type r; }; - regex:: - ~regex () + template <> + basic_regex:: + ~basic_regex () { delete impl_; } - regex:: - regex (regex const& r) + template <> + basic_regex:: + ~basic_regex () + { + delete impl_; + } + + template <> + basic_regex:: + basic_regex (basic_regex const& r) : impl_ (new impl (r.impl_->r)) { } - regex& regex:: - operator= (regex const& r) + template <> + basic_regex:: + basic_regex (basic_regex const& r) + : impl_ (new impl (r.impl_->r)) + { + } + + template <> + basic_regex& basic_regex:: + operator= (basic_regex const& r) + { + impl_->r = r.impl_->r; + return *this; + } + + template <> + basic_regex& basic_regex:: + operator= (basic_regex const& r) { impl_->r = r.impl_->r; return *this; } - void regex:: - init (string const* s) + template <> + void basic_regex:: + init (string_type const* s) { try { @@ -76,24 +104,60 @@ namespace cutl } catch (tr1::regex_error const& e) { - throw format (s == 0 ? "" : *s, e.what ()); + throw basic_format (s == 0 ? "" : *s, e.what ()); } } - bool regex:: - match (string const& s) const + template <> + void basic_regex:: + init (string_type const* s) + { + try + { + if (impl_ == 0) + impl_ = s == 0 ? new impl : new impl (*s); + else + impl_->r = *s; + } + catch (tr1::regex_error const& e) + { + throw basic_format (s == 0 ? L"" : *s, e.what ()); + } + } + + template <> + bool basic_regex:: + match (string_type const& s) const + { + return tr1::regex_match (s, impl_->r); + } + + template <> + bool basic_regex:: + match (string_type const& s) const { return tr1::regex_match (s, impl_->r); } - bool regex:: - search (string const& s) const + template <> + bool basic_regex:: + search (string_type const& s) const + { + return tr1::regex_search (s, impl_->r); + } + + template <> + bool basic_regex:: + search (string_type const& s) const { return tr1::regex_search (s, impl_->r); } - string regex:: - replace (string const& s, string const& sub, bool first_only) const + template <> + string basic_regex:: + replace (string_type const& s, + string_type const& sub, + bool first_only) const { tr1::regex_constants::match_flag_type f ( tr1::regex_constants::format_default); @@ -101,78 +165,50 @@ namespace cutl if (first_only) f |= tr1::regex_constants::format_first_only; - return regex_replace (s, impl_->r, sub, f); + return tr1::regex_replace (s, impl_->r, sub, f); } - string regex:: - str () const + template <> + wstring basic_regex:: + replace (string_type const& s, + string_type const& sub, + bool first_only) const { - return impl_->r.str (); + tr1::regex_constants::match_flag_type f ( + tr1::regex_constants::format_default); + + if (first_only) + f |= tr1::regex_constants::format_first_only; + + return tr1::regex_replace (s, impl_->r, sub, f); } - bool regex:: - empty () const + template <> + string basic_regex:: + str () const { - return impl_->r.empty (); + return impl_->r.str (); } - ostream& - operator<< (ostream& os, regex const& r) + template <> + wstring basic_regex:: + str () const { - return os << r.str ().c_str (); + return impl_->r.str (); } - // - // regexsub - // - void regexsub:: - init (string const& s) + template <> + bool basic_regex:: + empty () const { - string r; - string::size_type p (parse (s, 0, r)); - regex_ = r; - p = parse (s, p, sub_); - if (p + 1 < s.size ()) - throw format (s, "junk after third delimiter"); + return impl_->r.empty (); } - // - // parse() - // - string::size_type - parse (string const& s, string::size_type p, string& r) + template <> + bool basic_regex:: + empty () const { - r.clear (); - string::size_type n (s.size ()); - - if (p >= n) - throw format (s, "empty expression"); - - char d (s[p++]); - - for (; p < n; ++p) - { - if (s[p] == d) - break; - - if (s[p] == '\\') - { - if (++p < n) - { - if (s[p] != d && s[p] != '\\') - r += '\\'; - r += s[p]; - } - // else {we ran out of stuff before finding the delimiter} - } - else - r += s[p]; - } - - if (p == n) - throw format (s, "missing closing delimiter"); - - return p; + return impl_->r.empty (); } } } diff --git a/cutl/re/re.txx b/cutl/re/re.txx new file mode 100644 index 0000000..9c4122b --- /dev/null +++ b/cutl/re/re.txx @@ -0,0 +1,69 @@ +// file : cutl/re/re.txx +// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +namespace cutl +{ + namespace re + { + // + // basic_regexsub + // + template + void basic_regexsub:: + init (string_type const& s) + { + string_type r; + typename string_type::size_type p (parse (s, 0, r)); + regex_ = r; + p = parse (s, p, sub_); + if (p + 1 < s.size ()) + throw basic_format (s, "junk after third delimiter"); + } + + // + // parse() + // + template + typename std::basic_string::size_type + parse (std::basic_string const& s, + typename std::basic_string::size_type p, + std::basic_string& r) + { + r.clear (); + typename std::basic_string::size_type n (s.size ()); + + if (p >= n) + throw basic_format (s, "empty expression"); + + char d (s[p++]); + + for (; p < n; ++p) + { + if (s[p] == d) + break; + + if (s[p] == '\\') + { + if (++p < n) + { + // Pass the escape sequence through unless it is the delimiter. + // + if (s[p] != d) + r += '\\'; + + r += s[p]; + } + // else {We ran out of stuff before finding the delimiter.} + } + else + r += s[p]; + } + + if (p == n) + throw basic_format (s, "missing closing delimiter"); + + return p; + } + } +} -- cgit v1.1