Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions cpp/Platform.Data/CLinks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ο»Ώ#pragma once
#include <vector>
#include <concepts>

namespace Platform::Data
{
template<typename T>
concept CLinks = requires(T& links, const T& constLinks,
const std::vector<typename T::LinkAddressType>& restriction,
const std::vector<typename T::LinkAddressType>& substitution,
const typename T::ReadHandlerType& readHandler,
const typename T::WriteHandlerType& writeHandler)
{
// Type aliases that must exist
typename T::LinkAddressType;
typename T::LinksOptionsType;
typename T::LinkType;
typename T::ReadHandlerType;
typename T::WriteHandlerType;

// Constants must exist
T::Constants;

// Core methods that must exist
{ constLinks.Count(restriction) } -> std::convertible_to<typename T::LinkAddressType>;
{ constLinks.Each(restriction, readHandler) } -> std::convertible_to<typename T::LinkAddressType>;
{ links.Create(substitution, writeHandler) } -> std::convertible_to<typename T::LinkAddressType>;
{ links.Update(restriction, substitution, writeHandler) } -> std::convertible_to<typename T::LinkAddressType>;
{ links.Delete(restriction, writeHandler) } -> std::convertible_to<typename T::LinkAddressType>;
};
}
39 changes: 25 additions & 14 deletions cpp/Platform.Data/ILinksExtensions.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
ο»Ώnamespace Platform::Data
ο»Ώ#pragma once
#include "CLinks.h"
#include "LinksConstantsExtensions.h"
#include "Point.h"
#include "Exceptions/ArgumentLinkDoesNotExistsException.h"
#include <Platform.Interfaces.h>

#define DIRECT_METHOD_CALL(TStorage, storage, method, ...) storage.method(__VA_ARGS__)
#define Ensures(condition) // TODO: Add proper assertion logic

namespace Platform::Data
{
using namespace Platform::Interfaces;
template<typename TStorage>

template<CLinks TStorage>
static typename TStorage::LinkAddressType Create(TStorage& storage, const typename TStorage::LinkType& substitution)
{
auto $continue { storage.Constants.Continue };
Expand All @@ -14,7 +25,7 @@
return createdLinkAddress;
}

template<typename TStorage>
template<CLinks TStorage>
static typename TStorage::LinkAddressType Create(TStorage& storage, std::convertible_to<typename TStorage::LinkAddressType> auto ...substitutionPack)
{
typename TStorage::LinkType substitution { static_cast<typename TStorage::LinkAddressType>(substitutionPack)... };
Expand All @@ -28,7 +39,7 @@
return createdLinkAddress;
}

template<typename TStorage>
template<CLinks TStorage>
static typename TStorage::LinkAddressType Update(TStorage& storage, const typename TStorage::LinkType& restriction, const typename TStorage::LinkType& substitution)
{
auto $continue{storage.Constants.Continue};
Expand All @@ -41,7 +52,7 @@
return updatedLinkAddress;
}

template<typename TStorage>
template<CLinks TStorage>
static typename TStorage::LinkAddressType Delete(TStorage& storage, const typename TStorage::LinkType& restriction)
{
auto $continue{storage.Constants.Continue};
Expand All @@ -54,7 +65,7 @@
return deletedLinkAddress;
}

template<typename TStorage>
template<CLinks TStorage>
static typename TStorage::LinkAddressType Delete(TStorage& storage, typename TStorage::LinkAddressType linkAddress)
{
auto $continue{storage.Constants.Continue};
Expand All @@ -67,30 +78,30 @@
return deletedLinkAddress;
}

template<typename TStorage>
template<CLinks TStorage>
static typename TStorage::LinkAddressType Count(const TStorage& storage, std::convertible_to<typename TStorage::LinkAddressType> auto ...restrictionPack)
// TODO: later add noexcept(expr)
{
typename TStorage::LinkType restriction { static_cast<typename TStorage::LinkAddressType>(restrictionPack)... };
return DIRECT_METHOD_CALL(TStorage, storage, Count, restriction);
}

template<typename TStorage>
template<CLinks TStorage>
static bool Exists(const TStorage& storage, typename TStorage::LinkAddressType linkAddress) noexcept
{
constexpr auto constants = storage.Constants;
return IsExternalReference<typename TStorage::LinkAddressType, constants>(linkAddress) || (IsInternalReference<typename TStorage::LinkAddressType, constants>(linkAddress) && DIRECT_METHOD_CALL(TStorage, storage, Count, linkAddress) > 0);
}

template<typename TStorage>
template<CLinks TStorage>
static typename TStorage::LinkAddressType Each(const TStorage& storage, const typename TStorage::ReadHandlerType& handler, std::convertible_to<typename TStorage::LinkAddressType> auto... restriction)
// TODO: later create noexcept(expr)
{
typename TStorage::LinkType restrictionContainer { static_cast<typename TStorage::LinkAddressType>(restriction)... };
return DIRECT_METHOD_CALL(TStorage, storage, Each, restrictionContainer, handler);
}

template<typename TStorage>
template<CLinks TStorage>
static typename TStorage::LinkType GetLink(const TStorage& storage, typename TStorage::LinkAddressType linkAddress)
{
constexpr auto constants = storage.Constants;
Expand All @@ -111,21 +122,21 @@
return resultLink;
}

template<typename TStorage>
template<CLinks TStorage>
static bool IsFullPoint(TStorage& storage, typename TStorage::LinkAddressType link)
{
if (IsExternalReference(storage.Constants, link))
if (IsExternalReference<typename TStorage::LinkAddressType, storage.Constants>(link))
{
return true;
}
Ensures(DIRECT_METHOD_CALL(TStorage, storage, Exists, link));
return Point<typename TStorage::LinkAddressType>::IsFullPoint(DIRECT_METHOD_CALL(TStorage, storage, GetLink, link));
}

template<typename TStorage>
template<CLinks TStorage>
static bool IsPartialPoint(TStorage& storage, typename TStorage::LinkAddressType link)
{
if (IsExternalReference(storage.Constants, link))
if (IsExternalReference<typename TStorage::LinkAddressType, storage.Constants>(link))
{
return true;
}
Expand Down
Loading