arrp 0.0.15
Auto returning resource pool for modern C++
Loading...
Searching...
No Matches
scoped_resource.hpp
1/*
2 scoped_resource
3
4 BSD 3-Clause License
5
6 Copyright (c) 2026, Abdulkareem Siddiq
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
11
12 1. Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14
15 2. Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
18
19 3. Neither the name of the copyright holder nor the names of its
20 contributors may be used to endorse or promote products derived from
21 this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#pragma once
37#ifndef SCOPED_RESOURCE_HPP
38#define SCOPED_RESOURCE_HPP
39
40#include <atomic>
41#include <concepts>
42#include <cstdint>
43#include <format>
44#include <functional>
45#include <stdexcept>
46#include <type_traits>
47
48#include "common.hpp"
49
50namespace siddiqsoft::arrp
51{
77 template <typename T>
78 concept NonNumericMoveConstructible = std::move_constructible<T> && !std::is_arithmetic_v<T>;
79
132 template <typename T>
135 {
136 // Allow resource_pool to access protected members
137 template <typename U, typename SRT, uint8_t IC>
138 requires((IC <= resource_pool_limits::MaxCapacity)) && NonNumericMoveConstructible<U> &&
139 std::derived_from<SRT, scoped_resource<U>>
140 friend class resource_pool;
141
142 protected:
145 T m_rsrc {};
146
150 std::function<void(T&&)> m_putback_callback {};
151
156 bool m_is_valid {false};
157
158 public:
168 scoped_resource() = delete;
169
203 explicit scoped_resource(T&& src, std::function<void(T&&)>&& f = {})
204 : m_rsrc(std::move(src))
205 , m_putback_callback(std::move(f))
206 , m_is_valid(true)
207 {
208 }
209
220 explicit scoped_resource(const T&) = delete;
221
246 scoped_resource(scoped_resource&& src) noexcept
247 : m_rsrc(std::move(src.m_rsrc))
248 , m_putback_callback(std::move(src.m_putback_callback))
249 , m_is_valid(src.m_is_valid)
250 {
251 // Reset to ensure that the source does not double return!
252 src.m_putback_callback = {};
253 src.m_is_valid = false;
254 }
255
278 scoped_resource& operator=(scoped_resource&& src) noexcept
279 {
280 if (this != &src) {
281 // Return current resource if valid
283 m_putback_callback(std::move(m_rsrc));
284 }
285
286 // Move from src
287 m_rsrc = std::move(src.m_rsrc);
288 m_putback_callback = std::move(src.m_putback_callback);
289 m_is_valid = src.m_is_valid;
290
291 // Reset src
292 src.m_putback_callback = {};
293 src.m_is_valid = false;
294 }
295 return *this;
296 }
297
323 scoped_resource& operator=(T&& src)
324 {
325 m_rsrc = std::move(src);
326 m_is_valid = true;
327 return *this;
328 }
329
338
357 auto operator*() -> T& { return m_rsrc; }
358
359 operator T&() { return m_rsrc; }
360
389 ~scoped_resource()
390 {
391 // Only return resource if it's valid and callback exists
392 // This prevents returning uninitialized or moved-out resources to the pool
394 m_putback_callback(std::move(m_rsrc));
395 m_is_valid = false;
397 }
398 }
399
434 void invalidate() { m_is_valid = false; }
435
436#if defined(NLOHMANN_JSON_VERSION_MAJOR)
437 nlohmann::json to_json() const
438 {
439 return {{"_typver", "siddiqsoft.arrp.scoped_resource/0.0.0"}, {"capacity", m_is_valid}, {"value", m_rsrc}};
440 }
441#endif
442 };
443} // namespace siddiqsoft::arrp
444
445#endif
RAII wrapper for managing resource lifecycle with automatic return to pool.
scoped_resource()=delete
Default constructor is deleted.
bool m_is_valid
Tracks whether the resource is valid and should be returned to pool.
std::function< void(T &&)> m_putback_callback
Callback function to return the resource to the pool.
T m_rsrc
The actual resource being wrapped.
scoped_resource(const T &)=delete
Copy constructor is deleted.
scoped_resource & operator=(const scoped_resource &)=delete
Copy assignment operator is deleted.
Concept for types that are move-constructible but not arithmetic.