flatten 20260225

This commit is contained in:
Timothy Prepscius
2026-02-25 12:39:24 -05:00
commit fa54be052a
315 changed files with 49791 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
// TJP COPYRIGHT HEADER
#pragma once
#include "Delegate.h"
namespace tjp::core::delegate_single {
template<typename Delegate_>
struct Delegator;
template<typename As_, typename Delegate_>
using SpecializedDelegator = delegate::SpecializedDelegator<As_, Delegate_>;
template<typename Delegate_>
using Token = delegate::Token<Delegate_, Delegator<Delegate_>>;
template<typename Token_>
using WeakToken = delegate::WeakToken<Token_>;
template<typename As_, typename Token_, typename Into_=StrongPtr<As_>>
using TokenTyped = delegate::TokenTyped<As_, Token_, Into_>;
} // namespace

View File

@@ -0,0 +1,54 @@
// TJP COPYRIGHT HEADER
#pragma once
#include "Delegate+Single.h"
#include "Delegate.hpp"
#include <tjp/core/ptr/Ptr.h>
namespace tjp {
namespace core {
namespace delegate_single {
template<typename Delegate_>
struct Delegator
{
using Delegate = Delegate_;
using TokenType = Token<Delegate>;
Delegate *delegate = nullptr;
virtual TokenType addDelegate(Delegate *delegate) = 0;
virtual void insertDelegate(Delegate *delegate_)
{
debug_assert(delegate == nullptr);
delegate = delegate_;
}
virtual void eraseDelegate(Delegate *delegate_)
{
debug_assert(delegate == delegate_);
delegate = nullptr;
}
template<typename F>
void eachDelegate(F &&f)
{
if (delegate)
f(delegate);
}
} ;
template<typename As, typename Delegator>
using SpecializedDelegator =
delegate::SpecializedDelegator<As, Delegator>;
template<typename As, typename Delegate>
using LockingDelegator =
delegate::LockingDelegatorOf<SpecializedDelegator<As, Delegator<Delegate>>>;
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,25 @@
// TJP COPYRIGHT HEADER
#pragma once
#include <tjp/core/ptr/Ptr.h>
namespace tjp::core::delegate {
template<typename Delegate_>
struct Delegator;
template<typename As_, typename Delegate_>
struct SpecializedDelegator;
template<typename Delegate_, typename DelegatorType_= Delegator<Delegate_>>
struct Token;
template<typename Token_>
struct WeakToken;
template<typename As_, typename Token_, typename Into_=StrongPtr<As_>>
struct TokenTyped;
} // namespace

View File

@@ -0,0 +1,342 @@
// TJP COPYRIGHT HEADER
#pragma once
#include "Delegate.h"
#include <tjp/core/ptr/Ptr.hpp>
#include <tjp/core/containers/List.h>
#include <tjp/core/containers/SafeIteration.hpp>
#include <tjp/core/containers/Function.h>
#include <tjp/core/algorithm/list_erase_value_one.hpp>
#include <any>
namespace tjp {
namespace core {
namespace delegate {
template<typename T>
auto strong_(T &&t)
{
return strong(std::forward<T>(t));
}
template<typename T, typename U>
auto cast_to_strong(const StrongPtr<U> &t)
{
return std::static_pointer_cast<T>(t);
}
template<typename T, typename U>
auto cast_to_strong(const WeakPtr<U> &t)
{
return cast_to_strong<T>(strong(t));
}
template<typename Delegate_, typename DelegatorType_>
struct Token
{
using Delegate = Delegate_;
using DelegatorType = DelegatorType_;
StrongPtr<DelegatorType> delegator;
Token (const Token &) = delete;
Token (Token &&rhs) :
delegator(std::move(rhs.delegator))
{}
Token() {}
Token(const StrongPtr<DelegatorType> &delegator_) :
delegator(delegator_)
{
}
~Token ()
{
debug_assert(delegator == nullptr);
}
Token &operator =(Token &&token_)
{
delegator = std::move(token_.delegator);
return *this;
}
void release(Delegate *delegate)
{
if (!delegator)
return;
delegator->eraseDelegate(delegate);
delegator = nullptr;
}
auto &get () { return delegator; }
auto &get () const { return delegator; }
template<typename T>
auto strong ()
{
return cast_to_strong<T>(delegator);
}
template<typename T>
auto strong () const
{
return cast_to_strong<T>(delegator);
}
template<typename T>
auto ptr ()
{
return static_cast<T *>(ptr_of(delegator));
}
template<typename T>
auto ptr () const
{
return static_cast<T *>(ptr_of(delegator));
}
auto &operator ->() { return get(); }
auto &operator ->() const { return get(); }
operator bool() const
{
return delegator != nullptr;
}
} ;
template<typename Token_>
struct WeakToken
{
using TokenType = Token_;
using Delegate = typename TokenType::Delegate;
using DelegatorType = typename TokenType::DelegatorType;
WeakPtr<DelegatorType> delegator;
WeakToken() {}
WeakToken (const WeakToken &) = delete;
WeakToken (TokenType &&rhs) :
delegator(weak(rhs.delegator))
{
rhs.delegator = nullptr;
}
WeakToken (WeakToken &&rhs) :
delegator(std::move(rhs.delegator))
{
}
WeakToken(const StrongPtr<DelegatorType> &delegator_) :
delegator(weak(delegator_))
{
}
~WeakToken ()
{
debug_assert(!strong_(delegator));
}
WeakToken &operator =(TokenType &&token_)
{
auto token = std::move(token_);
delegator = weak(token.delegator);
return *this;
}
WeakToken &operator =(WeakToken &&token_)
{
delegator = std::move(token_.delegator);
return *this;
}
void release(Delegate *delegate)
{
if (auto delegator_ = strong_(delegator))
delegator_->eraseDelegate(delegate);
delegator = {};
}
auto &get () { return delegator; }
auto &get () const { return delegator; }
template<typename T>
auto strong ()
{
return cast_to_strong<T>(delegator);
}
template<typename T>
auto strong () const
{
return cast_to_strong<T>(delegator);
}
} ;
template<typename As_, typename Token_, typename Into_>
struct TokenTyped : Token_
{
using Super = Token_;
using As = As_;
using Into = Into_;
using Token = Token_;
TokenTyped (const TokenTyped &) = delete;
TokenTyped() {}
TokenTyped(Token &&token_) :
Super(std::move(token_))
{
}
TokenTyped(TokenTyped &&token_) :
Super(std::move(token_))
{
}
TokenTyped &operator =(Token &&token_)
{
Super::operator=(std::move(token_));
return *this;
}
TokenTyped &operator =(TokenTyped &&token_)
{
Super::operator=(std::move(token_));
return *this;
}
auto strong ()
{
return Super::template strong<As>();
}
auto strong () const
{
return Super::template strong<As>();
}
auto ptr ()
{
return Super::template ptr<As>();
}
auto ptr () const
{
return Super::template ptr<As>();
}
auto operator ->() { return ptr(); }
const auto operator ->() const { return ptr(); }
} ;
template<typename T, typename U, typename V>
auto strong_token(TokenTyped<T, U, V> &t)
{
return t.strong();
}
template<typename Delegate_>
struct Delegator
{
using Delegate = Delegate_;
using Delegates = SafeIteration<List<Delegate *>>;
using TokenType = Token<Delegate>;
Delegates delegates;
virtual TokenType addDelegate(Delegate *delegate) = 0;
virtual void insertDelegate(Delegate *delegate)
{
delegates.push_back(delegate);
}
virtual void eraseDelegate(Delegate *delegate)
{
list_erase_value_one(delegates, delegate);
}
template<typename F>
void eachDelegate(F &&f)
{
for (auto *delegate: delegates)
f(delegate);
}
} ;
template<typename As_, typename Super_>
struct SpecializedDelegator : Super_
{
using Super = Super_;
using DelegatorType = Super;
using Delegate = typename Super::Delegate;
using TokenType = typename Super::TokenType;
using As = As_;
static void eraser(const StrongPtr<DelegatorType> &delegator, Delegate *delegate)
{
delegator->eraseDelegate(delegate);
}
TokenType addDelegate(Delegate *delegate) override
{
this->insertDelegate(delegate);
return TokenType(
std::static_pointer_cast<DelegatorType>(
strong_this(
static_cast<As *>(this)
)
)
);
}
} ;
template<typename Super_>
struct LockingDelegatorOf : Super_
{
TestMutex m;
using Super = Super_;
using Delegate = typename Super::Delegate;
using TokenType = typename Super::TokenType;
void insertDelegate(Delegate *delegate) override
{
auto l = lock_of(m);
return Super::insertDelegate(delegate);
}
void eraseDelegate(Delegate *delegate) override
{
auto l = lock_of(m);
return Super::eraseDelegate(delegate);
}
template<typename F>
void foreach(F &&f)
{
auto l = lock_of(m);
Super::foreach(std::forward<F>(f));
}
} ;
template<typename As, typename Delegate>
using LockingDelegator =
SpecializedDelegator<As, LockingDelegatorOf<Delegator<Delegate>>>;
} // namespace
} // namespace
} // namespace

View File

@@ -0,0 +1,141 @@
// TJP COPYRIGHT HEADER
#include <tjp/core/delegate/Delegate+Single.hpp>
#include <tjp/core/testing/catch.hpp>
#include <tjp/core/containers/Function.h>
#include <tjp/core/algorithm/unused.hpp>
#include <tjp/core/log/Log.h>
#include <tjp/core/log/LogOf.h>
#include <iostream>
namespace tjp::core::delegate_single {
namespace T1 {
struct D;
struct A {
A(const StrongPtr<D> &d);
~A();
using Token = Token<A>;
Token token;
int i;
};
struct D :
SpecializedDelegator<D, Delegator<A>>,
StrongThis<D>
{
} ;
A::A(const StrongPtr<D> &d) :
token(d->addDelegate(this))
{
i = 5;
}
A::~A()
{
token.release(this);
}
SCENARIO("delegate_single")
{
// xLogActivateStory("core::delegate");
GIVEN("structs")
{
auto d = strong<D>();
A a(d);
REQUIRE(a.i == 5);
REQUIRE(a.token.delegator == d);
}
GIVEN("sizeof")
{
sLogTest("testing", logVar(sizeof(std::any)) << logVar(sizeof(A)) << logVar(sizeof(D)) << logVar(sizeof(A::Token)));
}
}
} // namespace
namespace T2 {
struct A {
int a;
} ;
struct B : A, StrongThis<B> {
int b;
} ;
void doMemory()
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
using F = Function<void()>;
auto a = strong<A>();
F f = [a]() {
};
f();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
SCENARIO("delegate_single_memory")
{
// xLogActivateStory("core::delegate");
GIVEN("structs")
{
auto b = strong<B>();
b->a = 1;
b->b = 2;
auto a = strong_ptr_cast<A>(b);
REQUIRE(a->a == 1);
auto ab = std::static_pointer_cast<B>(a);
REQUIRE(ab->b == 2);
}
GIVEN("memory")
{
doMemory();
}
GIVEN("sizeof")
{
std::this_thread::sleep_for(std::chrono::milliseconds(250));
using F = Function<void()>;
auto a = strong<A>();
F f = [a]() {};
auto g = []() {};
unused(a);
unused(f);
unused(g);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
sLogTest("testing", logVar(sizeof(std::any)) << logVar(sizeof(Token<A>)) << logVar(sizeof(a)) << logVar(sizeof(F)) << logVar(sizeof(f))<< logVar(sizeof(g)));
}
}
} // namespace
} // namespace

View File

@@ -0,0 +1,201 @@
// TJP COPYRIGHT HEADER
#include <tjp/core/delegate/Delegate.hpp>
#include <tjp/core/testing/catch.hpp>
#include <tjp/core/containers/Function.h>
#include <tjp/core/algorithm/unused.hpp>
#include <tjp/core/log/Log.h>
#include <tjp/core/log/LogOf.h>
#include <iostream>
namespace tjp::core::delegate {
namespace T1 {
struct D;
struct To
{
To();
int i;
} ;
struct A : To {
A(const StrongPtr<D> &d);
A(){}
~A();
using Token = Token<To>;
Token token;
};
struct WA : To {
WA(const StrongPtr<D> &d);
WA() {}
~WA();
using Token = WeakToken<Token<To>>;
Token token;
};
struct D :
SpecializedDelegator<D, Delegator<To>>,
StrongThis<D>
{
} ;
To::To()
{
i = 5;
}
A::A(const StrongPtr<D> &d) :
token(d->addDelegate(this))
{
}
A::~A()
{
token.release(this);
}
WA::WA(const StrongPtr<D> &d) :
token(d->addDelegate(this))
{
}
WA::~WA()
{
token.release(this);
}
SCENARIO("delegate")
{
// xLogActivateStory("core::delegate");
GIVEN("strong")
{
auto d = strong<D>();
A a(d);
A b;
REQUIRE(a.i == 5);
REQUIRE(a.token.delegator == d);
{
TokenTyped<D, Token<To>> ad(d->addDelegate(&b));
REQUIRE(strong_token(ad) == d);
ad.release(&b);
}
}
GIVEN("weak")
{
auto d = strong<D>();
WA a(d);
REQUIRE(a.i == 5);
REQUIRE(strong(a.token.get()) == d);
}
GIVEN("weak")
{
auto d = strong<D>();
WA a(d);
REQUIRE(a.i == 5);
REQUIRE(strong(a.token.get()) == d);
}
GIVEN("sizeof")
{
sLogTest("testing", logVar(sizeof(std::any)) << logVar(sizeof(A)) << logVar(sizeof(D)) << logVar(sizeof(A::Token)));
}
}
} // namespace
namespace T2 {
struct A {
int a;
} ;
struct B : A, StrongThis<B> {
int b;
} ;
void doMemory()
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
using F = Function<void()>;
auto a = strong<A>();
F f = [a]() {
};
f();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
SCENARIO("delegate_memory")
{
// xLogActivateStory("core::delegate");
GIVEN("structs")
{
auto b = strong<B>();
b->a = 1;
b->b = 2;
auto a = strong_ptr_cast<A>(b);
REQUIRE(a->a == 1);
auto ab = std::static_pointer_cast<B>(a);
REQUIRE(ab->b == 2);
}
GIVEN("memory")
{
doMemory();
}
GIVEN("sizeof")
{
std::this_thread::sleep_for(std::chrono::milliseconds(250));
using F = Function<void()>;
auto a = strong<A>();
F f = [a]() {};
auto g = []() {};
unused(a);
unused(f);
unused(g);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
sLogTest("testing", logVar(sizeof(std::any)) << logVar(sizeof(Token<A>)) << logVar(sizeof(a)) << logVar(sizeof(F)) << logVar(sizeof(f))<< logVar(sizeof(g)));
}
}
} // namespace
} // namespace