Nobody can stop me using pointers, except myself#

I finally got tired of living without generic pointers in UE-Angelscript. Binding APIs was especially annoying when the lack of pointers made an empty state hard to express.

Below is just some simple test code for the three smart pointers and raw pointers after binding them. The binding code is complicated and easy to get wrong, so I am not posting it. Blowing up my own code is fine; I can fix it. Blowing up somebody else’s is another matter.

The three smart pointers should not cause much trouble beyond a crash from forgetting a null check. Raw pointers can slip into undefined behavior, UB, with very little effort. But if they only receive C++ API results, with constructors disabled so AS code cannot create them everywhere, that is manageable.

{
	TSharedPtr<FTestSmartPtr> Pointer = FTestSmartPtr::MakeSharedPtr();
	auto& Ref = Pointer.Get();

	Ref.TestInt = 999;

	{
		// OpAssign
		TSharedPtr<FTestSmartPtr> Pointer2 = Pointer;
		auto& Ref2 = Pointer2.Get();

		Ref2.TestInt = 123;

		T.AssertTrue(Ref.TestInt == Ref2.TestInt);

		T.AssertTrue(Pointer.GetSharedReferenceCount() == 2);
		T.AssertTrue(Pointer2.GetSharedReferenceCount() == 2);

		T.AssertTrue(!Pointer2.IsUnique());

		T.AssertTrue(FDataPtr::Create(Ref) == FDataPtr::Create(Ref2));
	}

	// Destruct
	T.AssertTrue(Pointer.GetSharedReferenceCount() == 1);

	// Reset
	Pointer.Reset();
	T.AssertTrue(!Pointer.IsValid());
	T.AssertTrue(Pointer.GetSharedReferenceCount() == 0);
}
{
	TSharedPtr<FTestStructInAS> P;
	P.Emplace();
	P.Get().TestInt = 90;

	TWeakPtr<FTestStructInAS> W(P);
	T.AssertTrue(W.IsValid());
	auto P2 = W.Pin();
	T.AssertTrue(P2.GetSharedReferenceCount() == 2);

	W.Reset();
	T.AssertTrue(!W.IsValid());

	W = TWeakPtr<FTestStructInAS>(P);
	T.AssertTrue(W.Pin().GetSharedReferenceCount() == 3);
	T.AssertTrue(P.GetSharedReferenceCount() == 2);

	auto W2 = W;
	T.AssertTrue(W2.Pin().GetSharedReferenceCount() == 3);

	T.AssertTrue(W.Pin().Get().TestInt == 90);

	auto W3 = P.ToWeakPtr();
	T.AssertTrue(W3.IsValid());
	T.AssertTrue(W3.Pin().Get().TestInt == 90);
	T.AssertTrue(W == W3);

	TWeakPtr<FTestStructInAS> W4;
	T.AssertTrue(W != W4);
}
{
	TUniquePtr<FTestSmartPtr> UniquePtr;
	FTestSmartPtr::MakeUniquePtr(UniquePtr);

	T.AssertTrue(UniquePtr.IsValid());

	UniquePtr.Get().TestInt = 99;
	UniquePtr.Reset();
	T.AssertTrue(!UniquePtr.IsValid());

	UniquePtr.Emplace();
	T.AssertTrue(UniquePtr.IsValid());
	UniquePtr.Get().TestInt = 99;

	UniquePtr.Emplace();
	T.AssertTrue(UniquePtr.IsValid());
	T.AssertTrue(UniquePtr.Get().TestInt == 0);
	}
{
	TRawPtr<FTestSmartPtr> RawPtr;
	T.AssertTrue(!RawPtr.IsValid());
	{
		RawPtr = FTestSmartPtr::MakeRawPtr();

		T.AssertTrue(RawPtr.IsValid());
		RawPtr.Get().TestInt = 9090;

		FTestSmartPtr::DeleteRawPtr(RawPtr);
		RawPtr.Reset();
	}
	T.AssertTrue(!RawPtr.IsValid());
 }

After all that tinkering, things finally feel comfortable. Nobody can stop me using pointers, unless I decide not to.

×

Contact

Feedback

Send bug reports and feedback on GitHub Issues.

Cooperation

For cooperation enquiries, email contact@cuviss.com.

×

About

Terms of Service

See the Community page for each plugin's license.

You may reference site content with attribution.

The software and documentation are provided "as is" without warranty.

Unreal Engine and other third-party projects and names are trademarks of their respective owners. soloAS is not affiliated with Epic Games or Hazelight.

Attribution and showcase requests are non-binding, as described on the home page.

Updated 2026-10-24

Privacy Policy

This site uses no analytics, cookies or tracking, and has no forms or third-party scripts.

The site is hosted on GitHub Pages. GitHub may process standard access logs under its Privacy Statement.

What you send by email is shared with us; what you send through GitHub Issues is shared with GitHub.

Updated 2026-10-24

Contents

Pages

On this page