The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
lua_ptr.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2020 - 2025
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13*/
14
15#pragma once
16
17#include <memory>
18template<typename T>
19class lua_ptr;
20
21/**
22 * Allows creation of lua_ptr<T> instances, but does not affect the lifetime of the T itself.
23 * This allows the instance of T to be deleted while the lua_ptr<T>s still exist.
24 *
25 * The implementation details are making a shared_ptr<non-owning raw pointer to T>, with that
26 * shared_ptr owned by the instance of T that's being pointed to, which is then used to create
27 * weak_ptrs. The lua_ptr is a wrapper to make sure that no-one gets a second non-temporary
28 * shared_ptr<non-owning raw pointer T>. As there's only one shared_ptr, the weak_ptrs become
29 * invalid (but defined behavior) when the instance of T is deleted, because that deletes the
30 * shared_ptr.
31 */
32template<typename T>
34{
35public:
36 enable_lua_ptr(T* tp) : self_(std::make_shared<T*>(tp)) {}
37
38 /**
39 * The weak_ptrs are pointing to o's shared_ptr's control block, so to keep existing
40 * weak_ptrs valid the existing control block is reused instead of replaced.
41 *
42 * After the move, the existing control block will point to the new T, and o.self_ will be
43 * empty (which is guaranteed by the specification for std::shared_ptr's move assignment
44 * operator).
45 */
47 {
48 *self_ = static_cast<T*>(this);
49 }
51 {
52 self_ = std::move(o.self_);
53 *self_ = static_cast<T*>(this);
54 return *this;
55 }
56private:
57 enable_lua_ptr(const enable_lua_ptr& o) = delete;
59 friend class lua_ptr<T>;
60 std::shared_ptr<T*> self_;
61};
62
63/** T must inherit enable_lua_ptr<T> */
64template<typename T>
66{
67public:
70 {
71 if(auto pp = self_.lock()) {
72 return *pp;
73 }
74 return nullptr;
75 }
77 {
78 return get_ptr();
79 }
80 operator bool() const
81 {
82 return bool(self_.lock());
83 }
84 bool operator!() const
85 {
86 return !operator bool();
87 }
88 std::weak_ptr<T*> self_;
89};
Allows creation of lua_ptr<T> instances, but does not affect the lifetime of the T itself.
Definition lua_ptr.hpp:34
enable_lua_ptr(enable_lua_ptr &&o)
The weak_ptrs are pointing to o's shared_ptr's control block, so to keep existing weak_ptrs valid the...
Definition lua_ptr.hpp:46
enable_lua_ptr(const enable_lua_ptr &o)=delete
std::shared_ptr< T * > self_
Definition lua_ptr.hpp:60
enable_lua_ptr(T *tp)
Definition lua_ptr.hpp:36
enable_lua_ptr & operator=(enable_lua_ptr &&o)
Definition lua_ptr.hpp:50
T must inherit enable_lua_ptr<T>
Definition lua_ptr.hpp:66
T * get_ptr()
Definition lua_ptr.hpp:69
bool operator!() const
Definition lua_ptr.hpp:84
lua_ptr(enable_lua_ptr< T > &o)
Definition lua_ptr.hpp:68
std::weak_ptr< T * > self_
Definition lua_ptr.hpp:88
T * operator->()
Definition lua_ptr.hpp:76
STL namespace.