From d9ef2046dd94c2c389445b9f1451e3af31c98217 Mon Sep 17 00:00:00 2001 From: Yevgen Muntyan <17531749+muntyan@users.noreply.github.com> Date: Tue, 16 May 2017 20:47:05 -0700 Subject: [PATCH] Make Regex and MatchInfo movable instead of allocating them on heap --- moo/moocpp/gstr.h | 5 --- moo/moocpp/regex.cpp | 81 +++++++++++++++++++++++++++++++++++++------- moo/moocpp/regex.h | 33 ++++++++++++------ 3 files changed, 90 insertions(+), 29 deletions(-) diff --git a/moo/moocpp/gstr.h b/moo/moocpp/gstr.h index 0e134a43..ad31a8ae 100644 --- a/moo/moocpp/gstr.h +++ b/moo/moocpp/gstr.h @@ -67,11 +67,6 @@ private: char* m_p; }; -class gstrbuilder -{ - -}; - namespace std { diff --git a/moo/moocpp/regex.cpp b/moo/moocpp/regex.cpp index a9499c6e..f13ec657 100644 --- a/moo/moocpp/regex.cpp +++ b/moo/moocpp/regex.cpp @@ -16,6 +16,8 @@ #pragma once #include "moocpp/regex.h" +#include "mooutils/mooutils-messages.h" +#include namespace g { @@ -30,12 +32,32 @@ Regex::~Regex() g_regex_unref(m_p); } -std::shared_ptr Regex::compile(const char* pattern, CompileFlags compile_options, MatchFlags match_options, GError** error) +Regex::Regex(Regex&& other) + : m_p(other.m_p) +{ + other.m_p = nullptr; +} + +Regex& Regex::operator=(Regex&& other) +{ + std::swap(m_p, other.m_p); + return *this; +} + +bool Regex::is_valid() const +{ + return m_p != nullptr; +} + +Regex::operator bool() const +{ + return m_p != nullptr; +} + +Regex Regex::compile(const char* pattern, CompileFlags compile_options, MatchFlags match_options, GError** error) { GRegex* p = g_regex_new(pattern, GRegexCompileFlags(compile_options), GRegexMatchFlags(match_options), error); - if (!p) - return nullptr; - return std::make_shared(p); + return Regex{p}; } const char* Regex::get_pattern() const @@ -93,35 +115,35 @@ bool Regex::match(const char *pattern, const char *string, CompileFlags compile_ return g_regex_match_simple(pattern, string, GRegexCompileFlags(compile_options), GRegexMatchFlags(match_options)); } -std::unique_ptr Regex::match(const char* string, MatchFlags match_options) const +MatchInfo Regex::match(const char* string, MatchFlags match_options) const { return match(string, -1, 0, match_options, nullptr); } -std::unique_ptr Regex::match(const gstr& string, MatchFlags match_options) const +MatchInfo Regex::match(const gstr& string, MatchFlags match_options) const { return match(string.get(), match_options); } -std::unique_ptr Regex::match(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const +MatchInfo Regex::match(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const { GMatchInfo* match_info = nullptr; if (!g_regex_match_full(m_p, string, string_len, start_position, GRegexMatchFlags(match_options), &match_info, error)) - return nullptr; - return std::make_unique(*this, match_info, true); + return MatchInfo(*this); + return MatchInfo(*this, match_info, true); } -std::unique_ptr Regex::match_all(const char* string, MatchFlags match_options) const +MatchInfo Regex::match_all(const char* string, MatchFlags match_options) const { return match_all(string, -1, 0, match_options, nullptr); } -std::unique_ptr Regex::match_all(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const +MatchInfo Regex::match_all(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const { GMatchInfo* match_info = nullptr; if (!g_regex_match_all_full(m_p, string, string_len, start_position, GRegexMatchFlags(match_options), &match_info, error)) - return nullptr; - return std::make_unique(*this, match_info, true); + return MatchInfo(*this); + return MatchInfo(*this, match_info, true); } std::vector Regex::split(const char* pattern, const char* string, CompileFlags compile_options, MatchFlags match_options) @@ -207,11 +229,17 @@ bool Regex::check_replacement(const char* replacement, bool& has_references, GEr } +MatchInfo::MatchInfo(const Regex& regex) + : MatchInfo(regex, nullptr, false) +{ +} + MatchInfo::MatchInfo(const Regex& regex, GMatchInfo* p, bool take_ownership) : m_regex(regex) , m_p(p) , m_own(take_ownership) { + moo_assert(m_p || !m_own); } MatchInfo::~MatchInfo() @@ -220,6 +248,32 @@ MatchInfo::~MatchInfo() g_match_info_free(m_p); } +MatchInfo::MatchInfo(MatchInfo&& other) + : m_regex(other.m_regex) + , m_p(other.m_p) + , m_own(other.m_own) +{ + other.m_own = false; +} + +MatchInfo& MatchInfo::operator=(MatchInfo&& other) +{ + std::swap(m_regex, other.m_regex); + std::swap(m_p, other.m_p); + std::swap(m_own, other.m_own); + return *this; +} + +bool MatchInfo::is_match() const +{ + return m_p != nullptr; +} + +MatchInfo::operator bool() const +{ + return is_match(); +} + const Regex& MatchInfo::get_regex() const { return m_regex; @@ -227,6 +281,7 @@ const Regex& MatchInfo::get_regex() const const char* MatchInfo::get_string() const { + g_return_val_if_fail(m_p != nullptr, nullptr); return g_match_info_get_string(m_p); } diff --git a/moo/moocpp/regex.h b/moo/moocpp/regex.h index a2eb8515..e398e114 100644 --- a/moo/moocpp/regex.h +++ b/moo/moocpp/regex.h @@ -75,8 +75,13 @@ public: ~Regex(); Regex(const Regex&) = delete; Regex& operator=(const Regex&) = delete; + Regex(Regex&&); + Regex& operator=(Regex&&); - static std::shared_ptr compile(const char* pattern, CompileFlags compile_options = COMPILE_FLAGS_NONE, MatchFlags match_options = MATCH_FLAGS_NONE, GError** error = nullptr); + bool is_valid() const; + operator bool() const; + + static Regex compile(const char* pattern, CompileFlags compile_options = COMPILE_FLAGS_NONE, MatchFlags match_options = MATCH_FLAGS_NONE, GError** error = nullptr); const char* get_pattern() const; int get_max_backref() const; @@ -93,11 +98,11 @@ public: static bool match(const char *pattern, const char *string, CompileFlags compile_options = COMPILE_FLAGS_NONE, MatchFlags match_options = MATCH_FLAGS_NONE); - std::unique_ptr match(const char* string, MatchFlags match_options = MATCH_FLAGS_NONE) const; - std::unique_ptr match(const gstr& string, MatchFlags match_options = MATCH_FLAGS_NONE) const; - std::unique_ptr match(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const; - std::unique_ptr match_all(const char* string, MatchFlags match_options = MATCH_FLAGS_NONE) const; - std::unique_ptr match_all(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const; + MatchInfo match(const char* string, MatchFlags match_options = MATCH_FLAGS_NONE) const; + MatchInfo match(const gstr& string, MatchFlags match_options = MATCH_FLAGS_NONE) const; + MatchInfo match(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const; + MatchInfo match_all(const char* string, MatchFlags match_options = MATCH_FLAGS_NONE) const; + MatchInfo match_all(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const; static std::vector split(const char* pattern, const char* string, CompileFlags compile_options = COMPILE_FLAGS_NONE, MatchFlags match_options = MATCH_FLAGS_NONE); std::vector split(const char* string, MatchFlags match_options = MATCH_FLAGS_NONE) const; @@ -117,10 +122,16 @@ private: class MatchInfo { public: - MatchInfo(const Regex& regex, GMatchInfo* p, bool take_ownership); - ~MatchInfo(); - MatchInfo(const MatchInfo&) = delete; - MatchInfo& operator=(const MatchInfo&) = delete; + MatchInfo(const Regex& regex); + MatchInfo(const Regex& regex, GMatchInfo* p, bool take_ownership); + ~MatchInfo(); + MatchInfo(const MatchInfo&) = delete; + MatchInfo& operator=(const MatchInfo&) = delete; + MatchInfo(MatchInfo&&); + MatchInfo& operator=(MatchInfo&&); + + bool is_match() const; + operator bool() const; const Regex& get_regex() const; const char* get_string() const; @@ -137,7 +148,7 @@ public: std::vector fetch_all() const; private: - const Regex& m_regex; + std::reference_wrapper m_regex; GMatchInfo* m_p; bool m_own; };