diff --git a/cpp/Platform.Data/CLinks.h b/cpp/Platform.Data/CLinks.h new file mode 100644 index 0000000..1a51091 --- /dev/null +++ b/cpp/Platform.Data/CLinks.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include + +namespace Platform::Data +{ + template + concept CLinks = requires(T& links, const T& constLinks, + const std::vector& restriction, + const std::vector& 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; + { constLinks.Each(restriction, readHandler) } -> std::convertible_to; + { links.Create(substitution, writeHandler) } -> std::convertible_to; + { links.Update(restriction, substitution, writeHandler) } -> std::convertible_to; + { links.Delete(restriction, writeHandler) } -> std::convertible_to; + }; +} \ No newline at end of file diff --git a/cpp/Platform.Data/ILinksExtensions.h b/cpp/Platform.Data/ILinksExtensions.h index eda9516..7021e6f 100644 --- a/cpp/Platform.Data/ILinksExtensions.h +++ b/cpp/Platform.Data/ILinksExtensions.h @@ -1,7 +1,18 @@ -namespace Platform::Data +#pragma once +#include "CLinks.h" +#include "LinksConstantsExtensions.h" +#include "Point.h" +#include "Exceptions/ArgumentLinkDoesNotExistsException.h" +#include + +#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 + + template static typename TStorage::LinkAddressType Create(TStorage& storage, const typename TStorage::LinkType& substitution) { auto $continue { storage.Constants.Continue }; @@ -14,7 +25,7 @@ return createdLinkAddress; } - template + template static typename TStorage::LinkAddressType Create(TStorage& storage, std::convertible_to auto ...substitutionPack) { typename TStorage::LinkType substitution { static_cast(substitutionPack)... }; @@ -28,7 +39,7 @@ return createdLinkAddress; } - template + template static typename TStorage::LinkAddressType Update(TStorage& storage, const typename TStorage::LinkType& restriction, const typename TStorage::LinkType& substitution) { auto $continue{storage.Constants.Continue}; @@ -41,7 +52,7 @@ return updatedLinkAddress; } - template + template static typename TStorage::LinkAddressType Delete(TStorage& storage, const typename TStorage::LinkType& restriction) { auto $continue{storage.Constants.Continue}; @@ -54,7 +65,7 @@ return deletedLinkAddress; } - template + template static typename TStorage::LinkAddressType Delete(TStorage& storage, typename TStorage::LinkAddressType linkAddress) { auto $continue{storage.Constants.Continue}; @@ -67,7 +78,7 @@ return deletedLinkAddress; } - template + template static typename TStorage::LinkAddressType Count(const TStorage& storage, std::convertible_to auto ...restrictionPack) // TODO: later add noexcept(expr) { @@ -75,14 +86,14 @@ return DIRECT_METHOD_CALL(TStorage, storage, Count, restriction); } - template + template static bool Exists(const TStorage& storage, typename TStorage::LinkAddressType linkAddress) noexcept { constexpr auto constants = storage.Constants; return IsExternalReference(linkAddress) || (IsInternalReference(linkAddress) && DIRECT_METHOD_CALL(TStorage, storage, Count, linkAddress) > 0); } - template + template static typename TStorage::LinkAddressType Each(const TStorage& storage, const typename TStorage::ReadHandlerType& handler, std::convertible_to auto... restriction) // TODO: later create noexcept(expr) { @@ -90,7 +101,7 @@ return DIRECT_METHOD_CALL(TStorage, storage, Each, restrictionContainer, handler); } - template + template static typename TStorage::LinkType GetLink(const TStorage& storage, typename TStorage::LinkAddressType linkAddress) { constexpr auto constants = storage.Constants; @@ -111,10 +122,10 @@ return resultLink; } - template + template static bool IsFullPoint(TStorage& storage, typename TStorage::LinkAddressType link) { - if (IsExternalReference(storage.Constants, link)) + if (IsExternalReference(link)) { return true; } @@ -122,10 +133,10 @@ return Point::IsFullPoint(DIRECT_METHOD_CALL(TStorage, storage, GetLink, link)); } - template + template static bool IsPartialPoint(TStorage& storage, typename TStorage::LinkAddressType link) { - if (IsExternalReference(storage.Constants, link)) + if (IsExternalReference(link)) { return true; }