aboutsummaryrefslogtreecommitdiff
path: root/cutl
diff options
context:
space:
mode:
Diffstat (limited to 'cutl')
-rw-r--r--cutl/re.hxx177
-rw-r--r--cutl/re/re.cxx202
-rw-r--r--cutl/re/re.txx69
3 files changed, 287 insertions, 161 deletions
diff --git a/cutl/re.hxx b/cutl/re.hxx
index 3c47852..7638bb4 100644
--- a/cutl/re.hxx
+++ b/cutl/re.hxx
@@ -6,7 +6,7 @@
#define CUTL_RE_HXX
#include <string>
-#include <iosfwd> // std::ostream
+#include <ostream>
#include <cutl/exception.hxx>
#include <cutl/details/export.hxx>
@@ -15,21 +15,12 @@ namespace cutl
{
namespace re
{
- struct LIBCUTL_EXPORT format: exception
+ struct LIBCUTL_EXPORT format_base: exception
{
virtual
- ~format () throw ();
+ ~format_base () throw ();
- format (std::string const& e, std::string const& d)
- : regex_ (e), description_ (d)
- {
- }
-
- std::string const&
- regex () const
- {
- return regex_;
- }
+ format_base (std::string const& d): description_ (d) {}
std::string const&
description () const
@@ -40,56 +31,72 @@ namespace cutl
virtual char const*
what () const throw ();
- private:
- std::string regex_;
+ protected:
std::string description_;
};
- // Regular expression pattern.
- //
- struct LIBCUTL_EXPORT regex
+ template <typename C>
+ struct basic_format: format_base
{
- ~regex ();
+ virtual
+ ~basic_format () throw () {}
+
+ basic_format (std::basic_string<C> const& e, std::string const& d)
+ : format_base (d), regex_ (e) {}
- regex ()
- : impl_ (0)
+ std::basic_string<C> const&
+ regex () const
{
- init (0);
+ return regex_;
}
+ private:
+ std::basic_string<C> regex_;
+ };
+
+ typedef basic_format<char> format;
+ typedef basic_format<wchar_t> wformat;
+
+ // Regular expression pattern.
+ //
+ template <typename C>
+ struct basic_regex
+ {
+ typedef std::basic_string<C> string_type;
+
+ ~basic_regex ();
+
+ basic_regex (): impl_ (0) {init (0);}
+
explicit
- regex (std::string const& s)
- : impl_ (0)
- {
- init (&s);
- }
+ basic_regex (string_type const& s): impl_ (0) {init (&s);}
- regex&
- operator= (std::string const& s)
+ basic_regex&
+ operator= (string_type const& s)
{
init (&s);
return *this;
}
- regex (regex const&);
+ basic_regex (basic_regex const&);
- regex&
- operator= (regex const&);
+ basic_regex&
+ operator= (basic_regex const&);
public:
bool
- match (std::string const&) const;
+ match (string_type const&) const;
bool
- search (std::string const&) const;
+ search (string_type const&) const;
- std::string
- replace (std::string const& s,
- std::string const& sub,
+ string_type
+ replace (string_type const& s,
+ string_type const& sub,
bool first_only = false) const;
public:
- std::string
+ string_type
str () const;
bool
@@ -97,25 +104,32 @@ namespace cutl
private:
void
- init (std::string const*);
+ init (string_type const*);
private:
struct impl;
impl* impl_;
};
- LIBCUTL_EXPORT std::ostream&
- operator<< (std::ostream&, regex const&);
+ template <typename C>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, basic_regex<C> const& r)
+ {
+ return os << r.str ();
+ }
+
+ typedef basic_regex<char> regex;
+ typedef basic_regex<wchar_t> wregex;
// Regular expression pattern and substituation.
//
- struct LIBCUTL_EXPORT regexsub
+ template <typename C>
+ struct basic_regexsub
{
- typedef re::regex regex_type;
+ typedef basic_regex<C> regex_type;
+ typedef std::basic_string<C> string_type;
- regexsub ()
- {
- }
+ basic_regexsub () {}
// Expression is of the form /regex/substitution/ where '/' can
// be replaced with any delimiter. Delimiters must be escaped in
@@ -124,23 +138,20 @@ namespace cutl
// sequence (e.g., "\\").
//
explicit
- regexsub (std::string const& e)
- {
- init (e);
- }
+ basic_regexsub (string_type const& e) {init (e);}
- regexsub (std::string const& regex, std::string const& sub)
+ basic_regexsub (string_type const& regex, string_type const& sub)
: regex_ (regex), sub_ (sub)
{
}
- regexsub (regex_type const& regex, std::string const& sub)
+ basic_regexsub (regex_type const& regex, string_type const& sub)
: regex_ (regex), sub_ (sub)
{
}
- regexsub&
- operator= (std::string const& e)
+ basic_regexsub&
+ operator= (string_type const& e)
{
init (e);
return *this;
@@ -148,19 +159,19 @@ namespace cutl
public:
bool
- match (std::string const& s) const
+ match (string_type const& s) const
{
return regex_.match (s);
}
bool
- search (std::string const& s) const
+ search (string_type const& s) const
{
return regex_.search (s);
}
- std::string
- replace (std::string const& s, bool first_only = false) const
+ string_type
+ replace (string_type const& s, bool first_only = false) const
{
return regex_.replace (s, sub_, first_only);
}
@@ -172,7 +183,7 @@ namespace cutl
return regex_;
}
- const std::string&
+ const string_type&
substitution () const
{
return sub_;
@@ -186,45 +197,52 @@ namespace cutl
private:
void
- init (std::string const&);
+ init (string_type const&);
private:
regex_type regex_;
- std::string sub_;
+ string_type sub_;
};
+ typedef basic_regexsub<char> regexsub;
+ typedef basic_regexsub<wchar_t> wregexsub;
+
// Once-off regex execution.
//
+ template <typename C>
inline bool
- match (std::string const& s, std::string const& regex)
+ match (std::basic_string<C> const& s, std::basic_string<C> const& regex)
{
- re::regex r (regex);
+ basic_regex<C> r (regex);
return r.match (s);
}
+ template <typename C>
inline bool
- search (std::string const& s, std::string const& regex)
+ search (std::basic_string<C> const& s, std::basic_string<C> const& regex)
{
- re::regex r (regex);
+ basic_regex<C> r (regex);
return r.search (s);
}
- inline std::string
- replace (std::string const& s,
- std::string const& regex,
- std::string const& sub,
+ template <typename C>
+ inline std::basic_string<C>
+ replace (std::basic_string<C> const& s,
+ std::basic_string<C> const& regex,
+ std::basic_string<C> const& sub,
bool first_only = false)
{
- re::regex r (regex);
+ basic_regex<C> r (regex);
return r.replace (s, sub, first_only);
}
- inline std::string
- replace (std::string const& s,
- std::string const& regexsub, // /regex/subst/
+ template <typename C>
+ inline std::basic_string<C>
+ replace (std::basic_string<C> const& s,
+ std::basic_string<C> const& regexsub, // /regex/subst/
bool first_only = false)
{
- re::regexsub r (regexsub);
+ basic_regexsub<C> r (regexsub);
return r.replace (s, first_only);
}
@@ -234,11 +252,14 @@ namespace cutl
// the unescaped chunk in result or throws the format exception if
// the expression is invalid.
//
- LIBCUTL_EXPORT std::string::size_type
- parse (std::string const& s,
- std::string::size_type start,
- std::string& result);
+ template <typename C>
+ typename std::basic_string<C>::size_type
+ parse (std::basic_string<C> const& s,
+ typename std::basic_string<C>::size_type start,
+ std::basic_string<C>& result);
}
}
+#include <cutl/re/re.txx>
+
#endif // CUTL_RE_HXX
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 <ostream>
-
#include <cutl/re.hxx>
#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 <typename C>
+ struct basic_regex<C>::impl
{
+ typedef basic_string<C> string_type;
+ typedef tr1::basic_regex<C> 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<char>::
+ ~basic_regex ()
{
delete impl_;
}
- regex::
- regex (regex const& r)
+ template <>
+ basic_regex<wchar_t>::
+ ~basic_regex ()
+ {
+ delete impl_;
+ }
+
+ template <>
+ basic_regex<char>::
+ basic_regex (basic_regex const& r)
: impl_ (new impl (r.impl_->r))
{
}
- regex& regex::
- operator= (regex const& r)
+ template <>
+ basic_regex<wchar_t>::
+ basic_regex (basic_regex const& r)
+ : impl_ (new impl (r.impl_->r))
+ {
+ }
+
+ template <>
+ basic_regex<char>& basic_regex<char>::
+ operator= (basic_regex const& r)
+ {
+ impl_->r = r.impl_->r;
+ return *this;
+ }
+
+ template <>
+ basic_regex<wchar_t>& basic_regex<wchar_t>::
+ operator= (basic_regex const& r)
{
impl_->r = r.impl_->r;
return *this;
}
- void regex::
- init (string const* s)
+ template <>
+ void basic_regex<char>::
+ 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<char> (s == 0 ? "" : *s, e.what ());
}
}
- bool regex::
- match (string const& s) const
+ template <>
+ void basic_regex<wchar_t>::
+ 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<wchar_t> (s == 0 ? L"" : *s, e.what ());
+ }
+ }
+
+ template <>
+ bool basic_regex<char>::
+ match (string_type const& s) const
+ {
+ return tr1::regex_match (s, impl_->r);
+ }
+
+ template <>
+ bool basic_regex<wchar_t>::
+ match (string_type const& s) const
{
return tr1::regex_match (s, impl_->r);
}
- bool regex::
- search (string const& s) const
+ template <>
+ bool basic_regex<char>::
+ search (string_type const& s) const
+ {
+ return tr1::regex_search (s, impl_->r);
+ }
+
+ template <>
+ bool basic_regex<wchar_t>::
+ 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<char>::
+ 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<wchar_t>::
+ 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<char>::
+ str () const
{
- return impl_->r.empty ();
+ return impl_->r.str ();
}
- ostream&
- operator<< (ostream& os, regex const& r)
+ template <>
+ wstring basic_regex<wchar_t>::
+ str () const
{
- return os << r.str ().c_str ();
+ return impl_->r.str ();
}
- //
- // regexsub
- //
- void regexsub::
- init (string const& s)
+ template <>
+ bool basic_regex<char>::
+ 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<wchar_t>::
+ 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 <typename C>
+ void basic_regexsub<C>::
+ 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<C> (s, "junk after third delimiter");
+ }
+
+ //
+ // parse()
+ //
+ template <typename C>
+ typename std::basic_string<C>::size_type
+ parse (std::basic_string<C> const& s,
+ typename std::basic_string<C>::size_type p,
+ std::basic_string<C>& r)
+ {
+ r.clear ();
+ typename std::basic_string<C>::size_type n (s.size ());
+
+ if (p >= n)
+ throw basic_format<C> (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<C> (s, "missing closing delimiter");
+
+ return p;
+ }
+ }
+}