Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
hybrid-pointer.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Author: RafaƂ Siejakowski <rs@rs-math.net>
4 * Copyright (c) 2023
5 *
6 * Released under GNU GPL v2+, see the file 'COPYING' for more information.
7*/
12#ifndef SEEN_INKSCAPE_UTIL_HYBRID_POINTER_H
13#define SEEN_INKSCAPE_UTIL_HYBRID_POINTER_H
14
15#include <concepts>
16#include <memory>
17#include <variant>
18
19namespace Inkscape::Util {
20
26template<typename T>
28{
29 using OwningPtr = std::unique_ptr<T>;
30 using NonOwningPtr = T *;
31
32 std::variant<NonOwningPtr, OwningPtr> _pointer = nullptr;
33
34 HybridPointer(OwningPtr owning_pointer) { _pointer.template emplace<OwningPtr>(std::move(owning_pointer)); }
35 HybridPointer(NonOwningPtr nonowning_pointer) { _pointer.template emplace<NonOwningPtr>(nonowning_pointer); }
36
37public:
38 HybridPointer() = default;
39
40 template<typename DerivedType, typename... Args> requires std::is_base_of_v<T, DerivedType>
41 static HybridPointer make_owning(Args&& ...args) { return {std::make_unique<DerivedType>(args...)}; }
42 static HybridPointer make_nonowning(T *plain_pointer) { return {plain_pointer}; }
43
44 NonOwningPtr get() const {
45 if (NonOwningPtr const *plain_pointer = std::get_if<NonOwningPtr>(&_pointer)) {
46 return *plain_pointer;
47 }
48 return std::get<OwningPtr>(_pointer).get();
49 }
50
51 NonOwningPtr operator->() const { return get(); }
52 explicit operator bool() const { return bool(get()); }
53
55 HybridPointer &operator=(OwningPtr &&adopt) { _pointer = std::move(adopt); return *this; }
56};
57
58} // namespace Inkscape::Util
59
60#endif // SEEN_INKSCAPE_UTIL_HYBRID_POINTER_H
61
62/*
63 Local Variables:
64 mode:c++
65 c-file-style:"stroustrup"
66 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
67 indent-tabs-mode:nil
68 fill-column:99
69 End:
70*/
71// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
A helper class holding an owning or non-owning pointer depending on the memory management requirement...
std::variant< NonOwningPtr, OwningPtr > _pointer
std::unique_ptr< T > OwningPtr
HybridPointer(OwningPtr owning_pointer)
static HybridPointer make_nonowning(T *plain_pointer)
HybridPointer(NonOwningPtr nonowning_pointer)
HybridPointer & operator=(OwningPtr &&adopt)
Adopt an owning pointer.
static HybridPointer make_owning(Args &&...args)
NonOwningPtr operator->() const
Miscellaneous supporting code.
Definition document.h:93