medit/moo/moocpp/strutils.h

164 lines
4.0 KiB
C
Raw Normal View History

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();
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