flatten 20260225
This commit is contained in:
63
tjp/core/ptr/std/CustomControlBlock.h
Executable file
63
tjp/core/ptr/std/CustomControlBlock.h
Executable file
@@ -0,0 +1,63 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace tjp::core::ptr::using_std {
|
||||
|
||||
template <class _Tp, class _Dp, class _Alloc>
|
||||
class CustomControlBlock1
|
||||
: public std::__shared_weak_count
|
||||
{
|
||||
std::__compressed_pair<std::__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
CustomControlBlock1(_Tp __p, _Dp __d, _Alloc __a)
|
||||
: __data_(std::__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
|
||||
|
||||
#ifndef _LIBCPP_NO_RTTI
|
||||
virtual const void* __get_deleter(const std::type_info&) const _NOEXCEPT;
|
||||
#endif
|
||||
|
||||
private:
|
||||
virtual void __on_zero_shared() _NOEXCEPT;
|
||||
virtual void __on_zero_shared_weak() _NOEXCEPT;
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_NO_RTTI
|
||||
|
||||
template <class _Tp, class _Dp, class _Alloc>
|
||||
const void*
|
||||
CustomControlBlock1<_Tp, _Dp, _Alloc>::__get_deleter(const std::type_info& __t) const _NOEXCEPT
|
||||
{
|
||||
return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_NO_RTTI
|
||||
|
||||
template <class _Tp, class _Dp, class _Alloc>
|
||||
void
|
||||
CustomControlBlock1<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
|
||||
{
|
||||
__data_.first().second()(__data_.first().first());
|
||||
__data_.first().second().~_Dp();
|
||||
}
|
||||
|
||||
template <class _Tp, class _Dp, class _Alloc>
|
||||
void
|
||||
CustomControlBlock1<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
|
||||
{
|
||||
typedef typename std::__allocator_traits_rebind<_Alloc, CustomControlBlock1>::type _Al;
|
||||
typedef std::allocator_traits<_Al> _ATraits;
|
||||
typedef std::pointer_traits<typename _ATraits::pointer> _PTraits;
|
||||
|
||||
_Al __a(__data_.second());
|
||||
__data_.second().~_Alloc();
|
||||
// __a.deallocate(_PTraits::pointer_to(*this), 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
12
tjp/core/ptr/std/Ptr+Debug.h
Executable file
12
tjp/core/ptr/std/Ptr+Debug.h
Executable file
@@ -0,0 +1,12 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef DEBUG
|
||||
#define MEMORY_PTR_DEBUG_TYPE
|
||||
#endif
|
||||
|
||||
#define MEMORY_PTR_DEBUG_ALLOCATIONS
|
||||
#define LOG_MEMORY_PTR
|
||||
129
tjp/core/ptr/std/Ptr+GCC.h
Executable file
129
tjp/core/ptr/std/Ptr+GCC.h
Executable file
@@ -0,0 +1,129 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace tjp::core::ptr::using_std {
|
||||
|
||||
template<typename T, typename A>
|
||||
class StrongPtrAllocator
|
||||
{
|
||||
public:
|
||||
typedef A Allocator;
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
public:
|
||||
template<typename _Tp1> struct rebind {
|
||||
typedef StrongPtrAllocator<
|
||||
_Tp1,
|
||||
typename A::template rebind<_Tp1>::other
|
||||
> other;
|
||||
};
|
||||
|
||||
Allocator allocator;
|
||||
|
||||
public:
|
||||
StrongPtrAllocator() {}
|
||||
StrongPtrAllocator (const StrongPtrAllocator &) {}
|
||||
~StrongPtrAllocator () {}
|
||||
|
||||
template <class _Up>
|
||||
StrongPtrAllocator (const _Up &) { }
|
||||
|
||||
T *allocate (size_t size)
|
||||
{
|
||||
return allocator.allocate(size);
|
||||
}
|
||||
|
||||
void deallocate(T *t, size_t size)
|
||||
{
|
||||
return allocator.deallocate(t, size);
|
||||
}
|
||||
|
||||
void construct(pointer __p)
|
||||
{
|
||||
return allocator.construct(__p);
|
||||
}
|
||||
|
||||
template<typename U, typename... Args>
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
allocator.construct(p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void destroy(pointer p)
|
||||
{
|
||||
deallocate_detail(p);
|
||||
allocator.destroy(p);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
void destroy(U* p)
|
||||
{
|
||||
deallocate_detail(p);
|
||||
allocator.destroy(p);
|
||||
}
|
||||
} ;
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
auto strong_no_deallocate(Args && ...args)
|
||||
{
|
||||
return std::make_shared<T>(
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
auto strong_with_deallocate(Args && ...args)
|
||||
{
|
||||
return std::allocate_shared<T>(
|
||||
StrongPtrAllocator<T, std::allocator<T>>(),
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
auto strong(Args && ...args)
|
||||
{
|
||||
if constexpr (type_has_deallocate<T>::value) {
|
||||
return strong_with_deallocate<T>(
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return strong_no_deallocate<T>(
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename F>
|
||||
auto strong_with_delete(T *ptr, F &&f)
|
||||
{
|
||||
return std::shared_ptr<T>(
|
||||
ptr,
|
||||
makeDeleterWithFunction<T>(std::move(f))
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T, typename Allocator, typename ...Args>
|
||||
auto strong_with_allocator(Allocator allocator, Args&& ...args)
|
||||
{
|
||||
return std::allocate_shared<T>(
|
||||
StrongPtrAllocator<T, Allocator> { allocator },
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
34
tjp/core/ptr/std/Ptr+IO.h
Executable file
34
tjp/core/ptr/std/Ptr+IO.h
Executable file
@@ -0,0 +1,34 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace std {
|
||||
|
||||
template<typename IO, typename T>
|
||||
void io_ptr_allocate(IO &io, shared_ptr<T> &ptr)
|
||||
{
|
||||
io.allocate(ptr);
|
||||
}
|
||||
|
||||
template<typename IO, typename T>
|
||||
void io_ptr_allocate_default(IO &io, shared_ptr<T> &ptr)
|
||||
{
|
||||
ptr = tjp::core::ptr::using_std::strong<T>();
|
||||
}
|
||||
|
||||
template<typename IO, typename T>
|
||||
void io_w(IO &io, const shared_ptr<T> &r)
|
||||
{
|
||||
io.any(tjp::core::ptr::using_std::ptr_of(r));
|
||||
}
|
||||
|
||||
template<typename IO, typename T>
|
||||
void io_r(IO &io, shared_ptr<T> &t)
|
||||
{
|
||||
auto p = io.template pointer<T>(t);
|
||||
io.any(p);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
78
tjp/core/ptr/std/Ptr+LLVM.h
Executable file
78
tjp/core/ptr/std/Ptr+LLVM.h
Executable file
@@ -0,0 +1,78 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace tjp::core::ptr::using_std {
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
auto strong_no_deallocate(Args && ...args)
|
||||
{
|
||||
return std::make_shared<T>(
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
auto strong_with_deallocate(Args && ...args)
|
||||
{
|
||||
return std::shared_ptr<T>(
|
||||
new T(std::forward<Args>(args)...),
|
||||
makeDeleter<T>()
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
auto strong(Args && ...args)
|
||||
{
|
||||
if constexpr (type_has_deallocate<T>::value) {
|
||||
return strong_with_deallocate<T>(
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return strong_no_deallocate<T>(
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename F>
|
||||
auto strong_with_delete(T *ptr, F &&f)
|
||||
{
|
||||
return std::shared_ptr<T>(
|
||||
ptr,
|
||||
makeDeleterWithFunction<T>(std::move(f))
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T, typename Allocator, typename ... Args>
|
||||
auto strong_with_allocator(Allocator allocator, Args && ...args)
|
||||
{
|
||||
auto ptr = allocator.allocate(1);
|
||||
allocator.construct(ptr, std::forward<Args>(args)...);
|
||||
|
||||
auto f = makeDeleterWithAllocator<T>(allocator);
|
||||
typedef decltype(f) F;
|
||||
|
||||
typedef T *Tp;
|
||||
typedef std::__shared_ptr_pointer<Tp, F, Allocator> TControlBlock;
|
||||
using ControlBlockAllocator = typename Allocator::template rebind<TControlBlock>::other;
|
||||
|
||||
#ifdef _DEBUG
|
||||
auto controlBlockSize = sizeof(TControlBlock);
|
||||
(void)controlBlockSize;
|
||||
#endif
|
||||
|
||||
ControlBlockAllocator controlBlockAllocator;
|
||||
auto ctrl = controlBlockAllocator.allocate(1);
|
||||
controlBlockAllocator.construct(ctrl, ptr, f, allocator);
|
||||
|
||||
return std::shared_ptr<T>::__create_with_control_block(ptr, ctrl);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
38
tjp/core/ptr/std/Ptr+Log.h
Executable file
38
tjp/core/ptr/std/Ptr+Log.h
Executable file
@@ -0,0 +1,38 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../log/LogOf.h"
|
||||
#include "Ptr.h"
|
||||
|
||||
namespace std {
|
||||
|
||||
template<typename T>
|
||||
auto logOf(const std::shared_ptr<T> &v)
|
||||
{
|
||||
return tjp::core::logPtrValue(tjp::core::ptr::using_std::ptr_of(v));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto logOf(const std::weak_ptr<T> &v)
|
||||
{
|
||||
return tjp::core::logPtrValue(tjp::core::ptr::using_std::ptr_of(tjp::core::ptr::using_std::strong(v)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *logPtr(const std::shared_ptr<T> &v)
|
||||
{
|
||||
return tjp::core::ptr::using_std::ptr_of(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *logPtr(const std::weak_ptr<T> &v)
|
||||
{
|
||||
return tjp::core::ptr::using_std::ptr_of(strong(v));
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
140
tjp/core/ptr/std/Ptr.h
Executable file
140
tjp/core/ptr/std/Ptr.h
Executable file
@@ -0,0 +1,140 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "../../debug/Debug.h"
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct type_has_deallocate : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct type_has_deallocate<
|
||||
T,
|
||||
std::void_t<
|
||||
decltype(
|
||||
on_deallocate(
|
||||
std::declval<T *>()
|
||||
)
|
||||
)
|
||||
>
|
||||
> : std::true_type {};
|
||||
|
||||
template<typename T>
|
||||
void on_deallocate(T *t)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void deallocate_detail(T *t)
|
||||
{
|
||||
on_deallocate(t);
|
||||
}
|
||||
|
||||
namespace tjp::core::ptr::using_std {
|
||||
|
||||
template<typename T>
|
||||
auto makeDeleter()
|
||||
{
|
||||
return [](T *p) {
|
||||
deallocate_detail(p);
|
||||
delete p;
|
||||
} ;
|
||||
}
|
||||
|
||||
template<typename T, typename F>
|
||||
auto makeDeleterWithFunction(F &&f)
|
||||
{
|
||||
return [f](T *p) {
|
||||
deallocate_detail(p);
|
||||
f(p);
|
||||
} ;
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
auto makeDeleterWithAllocator(A a)
|
||||
{
|
||||
return [a](T *p) {
|
||||
deallocate_detail(p);
|
||||
|
||||
auto &a_ = const_cast<A &>(a);
|
||||
a_.destroy(p);
|
||||
a_.deallocate(p, 1);
|
||||
} ;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
using StrongPtr = std::shared_ptr<T>;
|
||||
|
||||
template<typename T>
|
||||
using WeakPtr = std::weak_ptr<T>;
|
||||
|
||||
template<typename T>
|
||||
using StrongThis = std::enable_shared_from_this<T>;
|
||||
|
||||
template<typename T, typename V>
|
||||
auto strong_ptr_dynamic_cast(const V &v)
|
||||
{
|
||||
return std::dynamic_pointer_cast<T>(v);
|
||||
}
|
||||
|
||||
template<typename T, typename V>
|
||||
auto strong_ptr_cast(const V &v)
|
||||
{
|
||||
return std::static_pointer_cast<T>(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto weak_this(T *t)
|
||||
{
|
||||
return t->weak_from_this();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto strong_this(T *t)
|
||||
{
|
||||
return std::static_pointer_cast<T>(t ? t->weak_from_this().lock() : std::shared_ptr<T>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto strong(const WeakPtr<T> &t)
|
||||
{
|
||||
return t.lock();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto weak(const StrongPtr<T> &t)
|
||||
{
|
||||
return std::weak_ptr<T>(t);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
auto strong_thread(const T &t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto ptr_of(const StrongPtr<T> &t)
|
||||
{
|
||||
return t.get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto ref_this(T *t)
|
||||
{
|
||||
return strong_this(t);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef _GLIBCXX_MEMORY
|
||||
#include "Ptr+GCC.h"
|
||||
#else
|
||||
#include "Ptr+LLVM.h"
|
||||
#endif
|
||||
Reference in New Issue
Block a user