From df1ef68cd8e8582724ce1192bfc202e0b9aeaf0c Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 28 Sep 2021 19:24:31 +0300 Subject: Get rid of C++ modules related code and rename *.mxx files to *.hxx --- libbutl/regex.hxx | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 libbutl/regex.hxx (limited to 'libbutl/regex.hxx') diff --git a/libbutl/regex.hxx b/libbutl/regex.hxx new file mode 100644 index 0000000..9b31075 --- /dev/null +++ b/libbutl/regex.hxx @@ -0,0 +1,133 @@ +// file : libbutl/regex.hxx -*- C++ -*- +// license : MIT; see accompanying LICENSE file + +#pragma once + +#include +#include +#include +#include // pair +#include // size_t + +#if defined(__clang__) +# if __has_include(<__config>) +# include <__config> // _LIBCPP_VERSION +# endif +#endif + +#include + +namespace butl +{ + // The regex semantics for the following functions is like that of + // std::regex_replace() extended the standard ECMA-262 substitution escape + // sequences with a subset of Perl sequences: + // + // \\, \n, \u, \l, \U, \L, \E, \1, ..., \9 + // + // Notes and limitations: + // + // - The only valid regex_constants flags are match_default, + // format_first_only and format_no_copy. + // + // - If backslash doesn't start any of the listed sequences then it is + // silently dropped and the following character is copied as is. + // + // - The character case conversion is performed according to the global + // C++ locale (which is, unless changed, is the same as C locale and + // both default to the POSIX locale aka "C"). + // + + // Call specified append() function for non-matched substrings and matched + // substring replacements returning true if search succeeded. The function + // must be callable with the following signature: + // + // void + // append(basic_string::iterator begin, basic_string::iterator end); + // + template + bool + regex_replace_search (const std::basic_string&, + const std::basic_regex&, + const std::basic_string& fmt, + F&& append, + std::regex_constants::match_flag_type = + std::regex_constants::match_default); + + // As above but concatenate non-matched substrings and matched substring + // replacements into a string returning it as well as whether the search + // succeeded. + // + template + std::pair, bool> + regex_replace_search (const std::basic_string&, + const std::basic_regex&, + const std::basic_string& fmt, + std::regex_constants::match_flag_type = + std::regex_constants::match_default); + + // Match the entire string and, if it matches, return the string replacement. + // + template + std::pair, bool> + regex_replace_match (const std::basic_string&, + const std::basic_regex&, + const std::basic_string& fmt); + + // As above but using match_results. + // + template + std::basic_string + regex_replace_match_results ( + const std::match_results::const_iterator>&, + const std::basic_string& fmt); + + template + std::basic_string + regex_replace_match_results ( + const std::match_results::const_iterator>&, + const C* fmt, std::size_t fmt_n); + + // Parse the '///' replacement string into the regex/format + // pair. Other character can be used as a delimiter instead of '/'. Throw + // std::invalid_argument or std::regex_error on parsing error. + // + // Note: escaping of the delimiter character is not (yet) supported. + // + template + std::pair, std::basic_string> + regex_replace_parse (const std::basic_string&, + std::regex_constants::syntax_option_type = + std::regex_constants::ECMAScript); + + template + std::pair, std::basic_string> + regex_replace_parse (const C*, + std::regex_constants::syntax_option_type = + std::regex_constants::ECMAScript); + + template + std::pair, std::basic_string> + regex_replace_parse (const C*, size_t, + std::regex_constants::syntax_option_type = + std::regex_constants::ECMAScript); + + // As above but return string instead of regex and do not fail if there is + // text after the last delimiter instead returning its position. + // + template + std::pair, std::basic_string> + regex_replace_parse (const C*, size_t, size_t& end); +} + +namespace std +{ + // Print regex error description but only if it is meaningful (this is also + // why we have to print leading colon). + // + LIBBUTL_SYMEXPORT ostream& + operator<< (ostream&, const regex_error&); +} + +#include +#include -- cgit v1.1