2016-01-01 22:25:53 -08:00
|
|
|
/*
|
|
|
|
* moocpp/strutils.h
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004-2015 by Yevgen Muntyan <emuntyan@users.sourceforge.net>
|
|
|
|
*
|
|
|
|
* This file is part of medit. medit is free software; you can
|
|
|
|
* redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU Lesser General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2.1 of the License,
|
|
|
|
* or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2016-01-19 03:54:06 -08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
2016-01-17 00:04:49 -08:00
|
|
|
#include <mooglib/moo-glib.h>
|
2016-01-01 22:25:53 -08:00
|
|
|
#include <moocpp/memutils.h>
|
2016-01-19 03:54:06 -08:00
|
|
|
#include <moocpp/utils.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <utility>
|
|
|
|
#include <functional>
|
2016-01-01 22:25:53 -08:00
|
|
|
|
|
|
|
namespace moo {
|
|
|
|
|
2016-01-17 00:04:49 -08:00
|
|
|
// Replacement for raw char*
|
|
|
|
class strp
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
strp() : m_p(nullptr) {}
|
|
|
|
~strp() { ::g_free(m_p); }
|
|
|
|
|
|
|
|
strp(strp&& s) : strp() { std::swap(m_p, s.m_p); }
|
|
|
|
strp& operator=(strp&& s) { std::swap(m_p, s.m_p); }
|
|
|
|
|
|
|
|
strp(const strp&) = delete;
|
|
|
|
strp& operator=(const strp&) = delete;
|
|
|
|
|
|
|
|
char* release() { char *p = m_p; m_p = nullptr; return p; }
|
|
|
|
const char* get() { return m_p; }
|
2016-01-17 03:49:15 -08:00
|
|
|
|
2016-01-17 00:04:49 -08:00
|
|
|
char*& p() { return m_p; }
|
2016-01-17 03:49:15 -08:00
|
|
|
char** pp() { return &m_p; }
|
|
|
|
operator char*() = delete;
|
|
|
|
char** operator&() = delete;
|
2016-01-17 00:04:49 -08:00
|
|
|
|
|
|
|
operator bool() const { return m_p != nullptr; }
|
|
|
|
bool operator !() const { return m_p == nullptr; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
char* m_p;
|
|
|
|
};
|
|
|
|
|
2016-01-03 05:13:00 -08:00
|
|
|
struct gstr_mem_handler
|
2016-01-01 22:25:53 -08:00
|
|
|
{
|
|
|
|
static char* dup(const char* p) { return p ? g_strdup (p) : nullptr; }
|
2016-01-04 03:56:42 -08:00
|
|
|
static void free(char* p) { ::g_free(p); }
|
2016-01-01 22:25:53 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
struct mg_get_string
|
|
|
|
{
|
|
|
|
static const char* get_string(const T& obj) { return static_cast<const char*>(obj); }
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename Self, typename GetString = mg_get_string<Self>>
|
2016-01-03 05:13:00 -08:00
|
|
|
class gstr_methods_mixin
|
2016-01-01 22:25:53 -08:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
char *strdup() const { return g_strdup(c_str()); }
|
|
|
|
|
|
|
|
bool empty() const { const char* s = c_str(); return !s || !*s; }
|
|
|
|
|
|
|
|
// These must not be called, to avoid ambiguity between an empty string and null
|
|
|
|
operator bool() const = delete;
|
|
|
|
bool operator!() const = delete;
|
|
|
|
|
2016-01-17 00:04:49 -08:00
|
|
|
char* operator*() const = delete;
|
|
|
|
|
2016-01-01 22:25:53 -08:00
|
|
|
private:
|
2016-01-02 07:09:54 -08:00
|
|
|
Self& self() { return static_cast<Self&>(*this); }
|
|
|
|
const Self& self() const { return static_cast<const Self&>(*this); }
|
2016-01-01 22:25:53 -08:00
|
|
|
const char* c_str() const { return GetString::get_string(static_cast<const Self&>(*this)); }
|
|
|
|
};
|
|
|
|
|
2016-01-03 05:13:00 -08:00
|
|
|
class gstr
|
|
|
|
: public mg_mem_holder<char, gstr_mem_handler, gstr>
|
|
|
|
, public gstr_methods_mixin<gstr>
|
2016-01-01 22:25:53 -08:00
|
|
|
{
|
2016-01-03 05:13:00 -08:00
|
|
|
using super = mg_mem_holder<char, gstr_mem_handler, gstr>;
|
2016-01-01 22:25:53 -08:00
|
|
|
|
|
|
|
public:
|
2016-01-03 05:13:00 -08:00
|
|
|
MOO_DECLARE_STANDARD_PTR_METHODS(gstr, super)
|
|
|
|
|
|
|
|
static const gstr null;
|
2016-01-01 22:25:53 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-01-03 05:13:00 -08:00
|
|
|
bool operator==(const gstr& s1, const char* s2);
|
|
|
|
bool operator==(const char* s1, const gstr& s2);
|
|
|
|
bool operator==(const gstr& s1, const gstr& s2);
|
|
|
|
bool operator!=(const gstr& s1, const char* s2);
|
|
|
|
bool operator!=(const char* s1, const gstr& s2);
|
|
|
|
bool operator!=(const gstr& s1, const gstr& s2);
|
2016-01-01 22:25:53 -08:00
|
|
|
|
2016-01-19 03:54:06 -08:00
|
|
|
|
|
|
|
class gerrp
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit gerrp(GError** errp = nullptr) : m_errp(errp ? errp : &m_local), m_local(nullptr) {}
|
|
|
|
|
|
|
|
~gerrp()
|
|
|
|
{
|
|
|
|
if (m_errp != &m_local)
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
operator bool() const { return (*m_errp) != nullptr; }
|
|
|
|
bool operator!() const { return (*m_errp) == nullptr; }
|
|
|
|
|
|
|
|
GError* get() const { return (*m_errp); }
|
|
|
|
GError* operator->() const { return (*m_errp); }
|
|
|
|
GError** operator&() { return m_errp; }
|
|
|
|
|
|
|
|
//void propagate(GError** dest) { g_propagate_error(dest, m_err); m_err = nullptr; }
|
|
|
|
void clear() { if (*m_errp) g_error_free(*m_errp); *m_errp = nullptr; m_local = nullptr; }
|
|
|
|
|
|
|
|
MOO_DISABLE_COPY_OPS(gerrp);
|
|
|
|
|
|
|
|
gerrp(gerrp&& other) = delete;
|
|
|
|
|
|
|
|
gerrp& operator=(gerrp&& other)
|
|
|
|
{
|
|
|
|
clear();
|
2016-01-20 22:58:04 -08:00
|
|
|
if (other)
|
|
|
|
g_propagate_error (m_errp, other.get());
|
2016-01-19 03:54:06 -08:00
|
|
|
other.m_errp = &other.m_local;
|
|
|
|
other.m_local = nullptr;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
GError** m_errp;
|
|
|
|
GError* m_local;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-01-01 22:25:53 -08:00
|
|
|
} // namespace moo
|
2016-01-17 00:04:49 -08:00
|
|
|
|
|
|
|
namespace std {
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct hash<moo::gstr>
|
|
|
|
{
|
|
|
|
const size_t operator()(const moo::gstr& s) const;
|
|
|
|
};
|
|
|
|
|
2016-01-19 03:54:06 -08:00
|
|
|
} // namespace std
|
|
|
|
|
|
|
|
#endif // __cplusplus
|