// SPDX-License-Identifier: GPL-2.0-or-later /* * Inkscape::Util::ptr_shared - like T const *, but stronger. * Used to hold c-style strings for objects that are managed by the gc. * * Authors: * MenTaLguY * * Copyright (C) 2006 MenTaLguY * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #ifndef SEEN_INKSCAPE_UTIL_SHARE_H #define SEEN_INKSCAPE_UTIL_SHARE_H #include "inkgc/gc-core.h" #include #include namespace Inkscape { namespace Util { class ptr_shared { public: ptr_shared() : _string(nullptr) {} ptr_shared(ptr_shared const &other) = default; operator char const *() const { return _string; } operator bool() const { return _string; } char const *pointer() const { return _string; } char const &operator[](int i) const { return _string[i]; } ptr_shared operator+(int i) const { return share_unsafe(_string+i); } ptr_shared operator-(int i) const { return share_unsafe(_string-i); } //WARNING: No bounds checking in += and -= functions. Moving the pointer //past the end of the string and then back could probably cause the garbage //collector to deallocate the string inbetween, as there's temporary no //valid reference pointing into the allocated space. ptr_shared &operator+=(int i) { _string += i; return *this; } ptr_shared &operator-=(int i) { _string -= i; return *this; } std::ptrdiff_t operator-(ptr_shared const &other) { return _string - other._string; } ptr_shared &operator=(ptr_shared const &other) = default; bool operator==(ptr_shared const &other) const { return _string == other._string; } bool operator!=(ptr_shared const &other) const { return _string != other._string; } bool operator>(ptr_shared const &other) const { return _string > other._string; } bool operator<(ptr_shared const &other) const { return _string < other._string; } friend ptr_shared share_unsafe(char const *string); private: ptr_shared(char const *string) : _string(string) {} static ptr_shared share_unsafe(char const *string) { return ptr_shared(string); } //This class (and code using it) assumes that it never has to free this //pointer, and that the memory it points to will not be freed as long as a //ptr_shared pointing to it exists. char const *_string; }; ptr_shared share_string(char const *string); ptr_shared share_string(char const *string, std::size_t length); inline ptr_shared share_unsafe(char const *string) { return ptr_shared::share_unsafe(string); } //TODO: Do we need this function? inline ptr_shared share_static_string(char const *string) { return share_unsafe(string); } } } #endif /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :