mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-05-28 02:35:32 +08:00
Update release
This commit is contained in:
+12
-1
@@ -1494,7 +1494,9 @@ UnitTestRemoteProtocol
|
|||||||
UnitTestRemoteProtocol_IOCommands
|
UnitTestRemoteProtocol_IOCommands
|
||||||
>::Type;
|
>::Type;
|
||||||
|
|
||||||
class UnitTestRemoteProtocol : public UnitTestRemoteProtocolFeatures
|
class UnitTestRemoteProtocol
|
||||||
|
: public UnitTestRemoteProtocolFeatures
|
||||||
|
, protected virtual IGuiRemoteEventProcessor
|
||||||
{
|
{
|
||||||
using EventPair = collections::Pair<Nullable<WString>, Func<void()>>;
|
using EventPair = collections::Pair<Nullable<WString>, Func<void()>>;
|
||||||
protected:
|
protected:
|
||||||
@@ -1551,6 +1553,8 @@ IGuiRemoteProtocol
|
|||||||
// TODO: Failure injection to disconnected
|
// TODO: Failure injection to disconnected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
void ProcessRemoteEvents() override
|
void ProcessRemoteEvents() override
|
||||||
{
|
{
|
||||||
#define ERROR_MESSAGE_PREFIX L"vl::presentation::unittest::UnitTestRemoteProtocol::ProcessRemoteEvents()#"
|
#define ERROR_MESSAGE_PREFIX L"vl::presentation::unittest::UnitTestRemoteProtocol::ProcessRemoteEvents()#"
|
||||||
@@ -1574,6 +1578,13 @@ IGuiRemoteProtocol
|
|||||||
}
|
}
|
||||||
#undef ERROR_MESSAGE_PREFIX
|
#undef ERROR_MESSAGE_PREFIX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-7
@@ -38512,7 +38512,10 @@ GuiRemoteController::INativeWindowService
|
|||||||
{
|
{
|
||||||
if (!connectionStopped)
|
if (!connectionStopped)
|
||||||
{
|
{
|
||||||
remoteProtocol->ProcessRemoteEvents();
|
if (auto processor = remoteProtocol->GetRemoteEventProcessor())
|
||||||
|
{
|
||||||
|
processor->ProcessRemoteEvents();
|
||||||
|
}
|
||||||
bool disconnected = false;
|
bool disconnected = false;
|
||||||
remoteMessages.Submit(disconnected);
|
remoteMessages.Submit(disconnected);
|
||||||
if (timerEnabled && !disconnected)
|
if (timerEnabled && !disconnected)
|
||||||
@@ -40838,9 +40841,9 @@ GuiRemoteProtocolFromJsonChannel
|
|||||||
channel->Submit(disconnected);
|
channel->Submit(disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiRemoteProtocolFromJsonChannel::ProcessRemoteEvents()
|
IGuiRemoteEventProcessor* GuiRemoteProtocolFromJsonChannel::GetRemoteEventProcessor()
|
||||||
{
|
{
|
||||||
channel->ProcessRemoteEvents();
|
return channel->GetRemoteEventProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -40989,9 +40992,9 @@ GuiRemoteJsonChannelFromProtocol
|
|||||||
protocol->Submit(disconnected);
|
protocol->Submit(disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiRemoteJsonChannelFromProtocol::ProcessRemoteEvents()
|
IGuiRemoteEventProcessor* GuiRemoteJsonChannelFromProtocol::GetRemoteEventProcessor()
|
||||||
{
|
{
|
||||||
protocol->ProcessRemoteEvents();
|
return protocol->GetRemoteEventProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -44614,9 +44617,9 @@ namespace vl::presentation::remote_renderer
|
|||||||
CHECK_FAIL(L"This function should not be called!");
|
CHECK_FAIL(L"This function should not be called!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiRemoteRendererSingle::ProcessRemoteEvents()
|
IGuiRemoteEventProcessor* GuiRemoteRendererSingle::GetRemoteEventProcessor()
|
||||||
{
|
{
|
||||||
CHECK_FAIL(L"This function should not be called!");
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+71
-25
@@ -23304,6 +23304,16 @@ IGuiRemoteProtocolConfig
|
|||||||
virtual WString GetExecutablePath() = 0;
|
virtual WString GetExecutablePath() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
IGuiRemoteEventProcessor
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
class IGuiRemoteEventProcessor : public virtual Interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void ProcessRemoteEvents() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
IGuiRemoteProtocol
|
IGuiRemoteProtocol
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
@@ -23313,9 +23323,9 @@ IGuiRemoteProtocol
|
|||||||
, public virtual IGuiRemoteProtocolMessages
|
, public virtual IGuiRemoteProtocolMessages
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Initialize(IGuiRemoteProtocolEvents* events) = 0;
|
virtual void Initialize(IGuiRemoteProtocolEvents* events) = 0;
|
||||||
virtual void Submit(bool& disconnected) = 0;
|
virtual void Submit(bool& disconnected) = 0;
|
||||||
virtual void ProcessRemoteEvents() = 0;
|
virtual IGuiRemoteEventProcessor* GetRemoteEventProcessor() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GuiRemoteEventCombinator : public Object, public virtual IGuiRemoteProtocolEvents
|
class GuiRemoteEventCombinator : public Object, public virtual IGuiRemoteProtocolEvents
|
||||||
@@ -23359,9 +23369,9 @@ IGuiRemoteProtocol
|
|||||||
targetProtocol->Submit(disconnected);
|
targetProtocol->Submit(disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessRemoteEvents() override
|
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
|
||||||
{
|
{
|
||||||
targetProtocol->ProcessRemoteEvents();
|
return targetProtocol->GetRemoteEventProcessor();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23396,9 +23406,9 @@ IGuiRemoteProtocol
|
|||||||
targetProtocol->Submit(disconnected);
|
targetProtocol->Submit(disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessRemoteEvents() override
|
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
|
||||||
{
|
{
|
||||||
targetProtocol->ProcessRemoteEvents();
|
return targetProtocol->GetRemoteEventProcessor();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23491,7 +23501,7 @@ IGuiRemoteProtocolChannel<T>
|
|||||||
virtual void Write(const TPackage& package) = 0;
|
virtual void Write(const TPackage& package) = 0;
|
||||||
virtual WString GetExecutablePath() = 0;
|
virtual WString GetExecutablePath() = 0;
|
||||||
virtual void Submit(bool& disconnected) = 0;
|
virtual void Submit(bool& disconnected) = 0;
|
||||||
virtual void ProcessRemoteEvents() = 0;
|
virtual IGuiRemoteEventProcessor* GetRemoteEventProcessor() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -23535,9 +23545,9 @@ Serialization
|
|||||||
channel->Submit(disconnected);
|
channel->Submit(disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessRemoteEvents() override
|
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
|
||||||
{
|
{
|
||||||
channel->ProcessRemoteEvents();
|
return channel->GetRemoteEventProcessor();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23719,11 +23729,18 @@ void ChannelPackageSemanticUnpack(
|
|||||||
~GuiRemoteProtocolAsyncChannelSerializerBase();
|
~GuiRemoteProtocolAsyncChannelSerializerBase();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define ENSURE_THREAD_ID(ID) CHECK_ERROR(ID == Thread::GetCurrentThreadId(), L"Expected to be called in thread: " ## #ID)
|
||||||
|
#else
|
||||||
|
#define ENSURE_THREAD_ID(ID) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename TPackage>
|
template<typename TPackage>
|
||||||
class GuiRemoteProtocolAsyncChannelSerializer
|
class GuiRemoteProtocolAsyncChannelSerializer
|
||||||
: public GuiRemoteProtocolAsyncChannelSerializerBase
|
: public GuiRemoteProtocolAsyncChannelSerializerBase
|
||||||
, public virtual IGuiRemoteProtocolChannel<TPackage>
|
, public virtual IGuiRemoteProtocolChannel<TPackage>
|
||||||
, protected virtual IGuiRemoteProtocolChannelReceiver<TPackage>
|
, protected virtual IGuiRemoteProtocolChannelReceiver<TPackage>
|
||||||
|
, protected virtual IGuiRemoteEventProcessor
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same_v<void, decltype(ChannelPackageSemanticUnpack(
|
std::is_same_v<void, decltype(ChannelPackageSemanticUnpack(
|
||||||
@@ -23747,6 +23764,9 @@ void ChannelPackageSemanticUnpack(
|
|||||||
collections::List<vint> requestIds;
|
collections::List<vint> requestIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vint threadIdUI = -1;
|
||||||
|
vint threadIdChannel = -1;
|
||||||
|
|
||||||
IGuiRemoteProtocolChannel<TPackage>* channel = nullptr;
|
IGuiRemoteProtocolChannel<TPackage>* channel = nullptr;
|
||||||
IGuiRemoteProtocolChannelReceiver<TPackage>* receiver = nullptr;
|
IGuiRemoteProtocolChannelReceiver<TPackage>* receiver = nullptr;
|
||||||
TUIMainProc uiMainProc;
|
TUIMainProc uiMainProc;
|
||||||
@@ -23775,6 +23795,7 @@ void ChannelPackageSemanticUnpack(
|
|||||||
|
|
||||||
void UIThreadProc()
|
void UIThreadProc()
|
||||||
{
|
{
|
||||||
|
threadIdUI = Thread::GetCurrentThreadId();
|
||||||
uiMainProc(this);
|
uiMainProc(this);
|
||||||
uiMainProc = {};
|
uiMainProc = {};
|
||||||
|
|
||||||
@@ -23800,6 +23821,7 @@ void ChannelPackageSemanticUnpack(
|
|||||||
// So that the implementation does not need to care about thread safety
|
// So that the implementation does not need to care about thread safety
|
||||||
|
|
||||||
// The thread stopped after receiving a signal from UIThreadProc
|
// The thread stopped after receiving a signal from UIThreadProc
|
||||||
|
threadIdChannel = Thread::GetCurrentThreadId();
|
||||||
while (!stopping)
|
while (!stopping)
|
||||||
{
|
{
|
||||||
eventAutoChannelTaskQueued.Wait();
|
eventAutoChannelTaskQueued.Wait();
|
||||||
@@ -23871,6 +23893,7 @@ void ChannelPackageSemanticUnpack(
|
|||||||
void Write(const TPackage& package) override
|
void Write(const TPackage& package) override
|
||||||
{
|
{
|
||||||
// Called from UI thread
|
// Called from UI thread
|
||||||
|
ENSURE_THREAD_ID(threadIdUI);
|
||||||
uiPendingPackages.Add(package);
|
uiPendingPackages.Add(package);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23879,6 +23902,7 @@ void ChannelPackageSemanticUnpack(
|
|||||||
// Called from UI thread
|
// Called from UI thread
|
||||||
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::channeling::GuiRemoteProtocolAsyncChannelSerializer<TPackage>::Submit(...)#"
|
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::channeling::GuiRemoteProtocolAsyncChannelSerializer<TPackage>::Submit(...)#"
|
||||||
|
|
||||||
|
ENSURE_THREAD_ID(threadIdUI);
|
||||||
SPIN_LOCK(lockConnection)
|
SPIN_LOCK(lockConnection)
|
||||||
{
|
{
|
||||||
if (!connectionAvailable)
|
if (!connectionAvailable)
|
||||||
@@ -23910,14 +23934,15 @@ void ChannelPackageSemanticUnpack(
|
|||||||
|
|
||||||
QueueToChannelThread([this, requestGroup, packages = std::move(uiPendingPackages)]()
|
QueueToChannelThread([this, requestGroup, packages = std::move(uiPendingPackages)]()
|
||||||
{
|
{
|
||||||
|
ENSURE_THREAD_ID(threadIdChannel);
|
||||||
for (auto&& package : packages)
|
for (auto&& package : packages)
|
||||||
{
|
{
|
||||||
channel->Write(package);
|
channel->Write(package);
|
||||||
}
|
}
|
||||||
bool disconnected = false;
|
bool disconnected = false;
|
||||||
channel->Submit(disconnected);
|
channel->Submit(disconnected);
|
||||||
if (disconnected)
|
if (disconnected)
|
||||||
{
|
{
|
||||||
SPIN_LOCK(lockConnection)
|
SPIN_LOCK(lockConnection)
|
||||||
{
|
{
|
||||||
if (requestGroup->connectionCounter == connectionCounter)
|
if (requestGroup->connectionCounter == connectionCounter)
|
||||||
@@ -23967,13 +23992,20 @@ void ChannelPackageSemanticUnpack(
|
|||||||
#undef ERROR_MESSAGE_PREFIX
|
#undef ERROR_MESSAGE_PREFIX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
void ProcessRemoteEvents() override
|
void ProcessRemoteEvents() override
|
||||||
{
|
{
|
||||||
// Called from UI thread
|
// Called from UI thread
|
||||||
QueueToChannelThread([this]()
|
ENSURE_THREAD_ID(threadIdUI);
|
||||||
|
if (channel->GetRemoteEventProcessor())
|
||||||
{
|
{
|
||||||
channel->ProcessRemoteEvents();
|
QueueToChannelThread([this]()
|
||||||
}, &eventAutoChannelTaskQueued);
|
{
|
||||||
|
ENSURE_THREAD_ID(threadIdChannel);
|
||||||
|
channel->GetRemoteEventProcessor()->ProcessRemoteEvents();
|
||||||
|
}, &eventAutoChannelTaskQueued);
|
||||||
|
}
|
||||||
|
|
||||||
FetchAndExecuteUITasks();
|
FetchAndExecuteUITasks();
|
||||||
|
|
||||||
@@ -24003,6 +24035,13 @@ void ChannelPackageSemanticUnpack(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -24091,9 +24130,11 @@ void ChannelPackageSemanticUnpack(
|
|||||||
void Initialize(IGuiRemoteProtocolChannelReceiver<TPackage>* _receiver) override
|
void Initialize(IGuiRemoteProtocolChannelReceiver<TPackage>* _receiver) override
|
||||||
{
|
{
|
||||||
// Called from UI thread
|
// Called from UI thread
|
||||||
|
ENSURE_THREAD_ID(threadIdUI);
|
||||||
receiver = _receiver;
|
receiver = _receiver;
|
||||||
QueueToChannelThreadAndWait([this]()
|
QueueToChannelThreadAndWait([this]()
|
||||||
{
|
{
|
||||||
|
ENSURE_THREAD_ID(threadIdChannel);
|
||||||
channel->Initialize(this);
|
channel->Initialize(this);
|
||||||
}, &eventAutoChannelTaskQueued);
|
}, &eventAutoChannelTaskQueued);
|
||||||
}
|
}
|
||||||
@@ -24101,16 +24142,19 @@ void ChannelPackageSemanticUnpack(
|
|||||||
IGuiRemoteProtocolChannelReceiver<TPackage>* GetReceiver() override
|
IGuiRemoteProtocolChannelReceiver<TPackage>* GetReceiver() override
|
||||||
{
|
{
|
||||||
// Called from UI thread
|
// Called from UI thread
|
||||||
|
ENSURE_THREAD_ID(threadIdUI);
|
||||||
return receiver;
|
return receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
WString GetExecutablePath() override
|
WString GetExecutablePath() override
|
||||||
{
|
{
|
||||||
// Called from UI thread
|
// Called from UI thread
|
||||||
|
ENSURE_THREAD_ID(threadIdUI);
|
||||||
if (!executablePath)
|
if (!executablePath)
|
||||||
{
|
{
|
||||||
QueueToChannelThreadAndWait([this]()
|
QueueToChannelThreadAndWait([this]()
|
||||||
{
|
{
|
||||||
|
ENSURE_THREAD_ID(threadIdChannel);
|
||||||
executablePath = channel->GetExecutablePath();
|
executablePath = channel->GetExecutablePath();
|
||||||
}, &eventAutoChannelTaskQueued);
|
}, &eventAutoChannelTaskQueued);
|
||||||
}
|
}
|
||||||
@@ -24119,6 +24163,8 @@ void ChannelPackageSemanticUnpack(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef ENSURE_THREAD_ID
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -24211,7 +24257,7 @@ GuiRemoteProtocolFromJsonChannel
|
|||||||
void Initialize(IGuiRemoteProtocolEvents* _events) override;
|
void Initialize(IGuiRemoteProtocolEvents* _events) override;
|
||||||
WString GetExecutablePath() override;
|
WString GetExecutablePath() override;
|
||||||
void Submit(bool& disconnected) override;
|
void Submit(bool& disconnected) override;
|
||||||
void ProcessRemoteEvents() override;
|
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -24274,7 +24320,7 @@ GuiRemoteJsonChannelFromProtocol
|
|||||||
void Write(const Ptr<glr::json::JsonObject>& package) override;
|
void Write(const Ptr<glr::json::JsonObject>& package) override;
|
||||||
WString GetExecutablePath() override;
|
WString GetExecutablePath() override;
|
||||||
void Submit(bool& disconnected) override;
|
void Submit(bool& disconnected) override;
|
||||||
void ProcessRemoteEvents() override;
|
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@@ -24799,14 +24845,14 @@ namespace vl::presentation::remote_renderer
|
|||||||
GuiRemoteRendererSingle();
|
GuiRemoteRendererSingle();
|
||||||
~GuiRemoteRendererSingle();
|
~GuiRemoteRendererSingle();
|
||||||
|
|
||||||
void RegisterMainWindow(INativeWindow* _window);
|
void RegisterMainWindow(INativeWindow* _window);
|
||||||
void UnregisterMainWindow();
|
void UnregisterMainWindow();
|
||||||
void ForceExitByFatelError();
|
void ForceExitByFatelError();
|
||||||
|
|
||||||
WString GetExecutablePath() override;
|
WString GetExecutablePath() override;
|
||||||
void Initialize(IGuiRemoteProtocolEvents* _events) override;
|
void Initialize(IGuiRemoteProtocolEvents* _events) override;
|
||||||
void Submit(bool& disconnected) override;
|
void Submit(bool& disconnected) override;
|
||||||
void ProcessRemoteEvents() override;
|
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override;
|
||||||
|
|
||||||
|
|
||||||
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE) void Request ## NAME() override;
|
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE) void Request ## NAME() override;
|
||||||
|
|||||||
@@ -1511,6 +1511,9 @@ UnitTest
|
|||||||
|
|
||||||
int UnitTest::RunAndDisposeTests(const collections::Array<WString>& options)
|
int UnitTest::RunAndDisposeTests(const collections::Array<WString>& options)
|
||||||
{
|
{
|
||||||
|
#ifdef VCZH_MSVC
|
||||||
|
_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
||||||
|
#endif
|
||||||
bool unrecognized = false;
|
bool unrecognized = false;
|
||||||
bool _D = false;
|
bool _D = false;
|
||||||
bool _R = false;
|
bool _R = false;
|
||||||
|
|||||||
+109
@@ -6075,6 +6075,115 @@ Range-Based For-Loop Iterator with Index
|
|||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Optimized Range-Based For-Loop Iterator for ArrayBase
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct RangeBasedForLoopIteratorForList
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const ArrayBase<T>& arrayBase;
|
||||||
|
vint index;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RangeBasedForLoopIteratorForList(const ArrayBase<T>& _arrayBase)
|
||||||
|
: arrayBase(_arrayBase)
|
||||||
|
, index(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator++()
|
||||||
|
{
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator*() const
|
||||||
|
{
|
||||||
|
return arrayBase.Get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const RangeBasedForLoopEnding&) const
|
||||||
|
{
|
||||||
|
return index >= arrayBase.Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const RangeBasedForLoopEnding&) const
|
||||||
|
{
|
||||||
|
return index < arrayBase.Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const RangeBasedForLoopEnding&, const RangeBasedForLoopIteratorForList<T>& iterator)
|
||||||
|
{
|
||||||
|
return iterator.index >= iterator.arrayBase.Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const RangeBasedForLoopEnding&, const RangeBasedForLoopIteratorForList<T>& iterator)
|
||||||
|
{
|
||||||
|
return iterator.index < iterator.arrayBase.Count();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
RangeBasedForLoopIteratorForList<T> begin(const ArrayBase<T>& arrayBase)
|
||||||
|
{
|
||||||
|
return { arrayBase };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
RangeBasedForLoopEnding end(const ArrayBase<T>& arrayBase)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Optimized Range-Based For-Loop Iterator for ArrayBase with Index
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct RangeBasedForLoopIteratorWithIndexForList : public RangeBasedForLoopIteratorForList<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RangeBasedForLoopIteratorWithIndexForList(const ArrayBase<T>& arrayBase)
|
||||||
|
: RangeBasedForLoopIteratorForList<T>(arrayBase)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple<const T&, vint> operator*() const
|
||||||
|
{
|
||||||
|
return { this->arrayBase.Get(this->index), this->index };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ArrayBaseWithIndex
|
||||||
|
{
|
||||||
|
const ArrayBase<T>& arrayBase;
|
||||||
|
|
||||||
|
ArrayBaseWithIndex(const ArrayBase<T>& _arrayBase)
|
||||||
|
: arrayBase(_arrayBase)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ArrayBaseWithIndex<T> indexed(const ArrayBase<T>& arrayBase)
|
||||||
|
{
|
||||||
|
return { arrayBase };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
RangeBasedForLoopIteratorWithIndexForList<T> begin(const ArrayBaseWithIndex<T>& wrapper)
|
||||||
|
{
|
||||||
|
return { wrapper.arrayBase };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
RangeBasedForLoopEnding end(const ArrayBaseWithIndex<T>& wrapper)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user