diff --git a/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h b/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h index 352f82da..652af843 100644 --- a/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h +++ b/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h @@ -1,20 +1,48 @@ -namespace Platform::Data::Exceptions +/// @file ArgumentLinkDoesNotExistsException.h +/// @brief Exception thrown when a referenced link does not exist. + +namespace Platform::Data::Exceptions { + /// @brief Generic template declaration for ArgumentLinkDoesNotExistsException. template class ArgumentLinkDoesNotExistsException; + + /// @brief Exception thrown when attempting to use a link address that doesn't exist. + /// @tparam TLinkAddress The type used for link addressing. + /// + /// This exception is thrown when operations reference a link that is not present + /// in the storage system, indicating an invalid link address was used. template class ArgumentLinkDoesNotExistsException : public std::invalid_argument { + /// @brief Constructs exception with link address and argument name. + /// @param link The non-existent link address. + /// @param argumentName The name of the argument that contained the invalid link. public: ArgumentLinkDoesNotExistsException(TLinkAddress link, std::string argumentName) : std::invalid_argument(FormatMessage(link, argumentName), argumentName) { } + /// @brief Constructs exception with link address only. + /// @param link The non-existent link address. public: ArgumentLinkDoesNotExistsException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) { } + /// @brief Constructs exception with custom message and inner exception. + /// @param message Custom error message. + /// @param innerException The underlying exception that caused this error. public: ArgumentLinkDoesNotExistsException(std::string message, const std::exception& innerException) : std::invalid_argument(message, innerException) { } + /// @brief Constructs exception with custom message. + /// @param message Custom error message. public: ArgumentLinkDoesNotExistsException(std::string message) : std::invalid_argument(message) { } + /// @brief Default constructor. public: ArgumentLinkDoesNotExistsException() { } + /// @brief Formats error message with link and argument name (in Russian). + /// @param link The non-existent link address. + /// @param argumentName The argument name. + /// @return Formatted error message. private: static std::string FormatMessage(TLinkAddress link, std::string argumentName) { return std::string("Связь [").append(Platform::Converters::To(link)).append("] переданная в аргумент [").append(argumentName).append("] не существует."); } + /// @brief Formats error message with link only (in Russian). + /// @param link The non-existent link address. + /// @return Formatted error message. private: static std::string FormatMessage(TLinkAddress link) { return std::string("Связь [").append(Platform::Converters::To(link)).append("] переданная в качестве аргумента не существует."); } }; } \ No newline at end of file diff --git a/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h b/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h index 06f47c1e..dfd3fb35 100644 --- a/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h +++ b/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h @@ -1,20 +1,48 @@ -namespace Platform::Data::Exceptions +/// @file ArgumentLinkHasDependenciesException.h +/// @brief Exception for links that cannot be modified due to dependencies. + +namespace Platform::Data::Exceptions { + /// @brief Generic template declaration for ArgumentLinkHasDependenciesException. template class ArgumentLinkHasDependenciesException; + + /// @brief Exception thrown when attempting to modify a link that has dependencies. + /// @tparam TLinkAddress The type used for link addressing. + /// + /// This exception indicates that a link cannot be modified or deleted because + /// other links depend on it, which would break referential integrity. template class ArgumentLinkHasDependenciesException : public std::invalid_argument { + /// @brief Constructs exception with link address and parameter name. + /// @param link The link that has dependencies. + /// @param paramName The parameter name that contained the link. public: ArgumentLinkHasDependenciesException(TLinkAddress link, std::string paramName) : std::invalid_argument(FormatMessage(link, paramName), paramName) { } + /// @brief Constructs exception with link address only. + /// @param link The link that has dependencies. public: ArgumentLinkHasDependenciesException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) { } + /// @brief Constructs exception with custom message and inner exception. + /// @param message Custom error message. + /// @param innerException The underlying exception. public: ArgumentLinkHasDependenciesException(std::string message, const std::exception& innerException) : std::invalid_argument(message, innerException) { } + /// @brief Constructs exception with custom message. + /// @param message Custom error message. public: ArgumentLinkHasDependenciesException(std::string message) : std::invalid_argument(message) { } + /// @brief Default constructor. public: ArgumentLinkHasDependenciesException() { } + /// @brief Formats error message with link and parameter name (in Russian). + /// @param link The link that has dependencies. + /// @param paramName The parameter name. + /// @return Formatted error message. private: static std::string FormatMessage(TLinkAddress link, std::string paramName) { return std::string("У связи [").append(Platform::Converters::To(link)).append("] переданной в аргумент [").append(paramName).append("] присутствуют зависимости, которые препятствуют изменению её внутренней структуры."); } + /// @brief Formats error message with link only (in Russian). + /// @param link The link that has dependencies. + /// @return Formatted error message. private: static std::string FormatMessage(TLinkAddress link) { return std::string("У связи [").append(Platform::Converters::To(link)).append("] переданной в качестве аргумента присутствуют зависимости, которые препятствуют изменению её внутренней структуры."); } }; } \ No newline at end of file diff --git a/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h b/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h index 5b2c69d5..f4a41225 100644 --- a/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h +++ b/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h @@ -1,13 +1,27 @@ -namespace Platform::Data::Exceptions +/// @file LinkWithSameValueAlreadyExistsException.h +/// @brief Exception for duplicate link creation attempts. + +namespace Platform::Data::Exceptions { + /// @brief Exception thrown when attempting to create a link that already exists. + /// + /// This exception is raised when the system prevents creation of duplicate links + /// with the same value, typically when uniqueness constraints are enforced. class LinkWithSameValueAlreadyExistsException : public std::exception { + /// @brief Default error message in Russian. public: inline static std::string DefaultMessage = "Связь с таким же значением уже существует."; + /// @brief Constructs exception with custom message and inner exception. + /// @param message Custom error message. + /// @param innerException The underlying exception. public: LinkWithSameValueAlreadyExistsException(std::string message, const std::exception& innerException) : base(message, innerException) { } + /// @brief Constructs exception with custom message. + /// @param message Custom error message. public: LinkWithSameValueAlreadyExistsException(std::string message) : base(message) { } + /// @brief Default constructor using default message. public: LinkWithSameValueAlreadyExistsException() : base(DefaultMessage) { } }; } diff --git a/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h b/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h index 521cb35c..f4d6c560 100644 --- a/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h +++ b/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h @@ -1,16 +1,34 @@ -namespace Platform::Data::Exceptions +/// @file LinksLimitReachedException.h +/// @brief Typed exception for link storage limit violations. + +namespace Platform::Data::Exceptions { + /// @brief Generic template declaration for LinksLimitReachedException. template class LinksLimitReachedException; + + /// @brief Typed exception thrown when link storage limits are reached. + /// @tparam TLinkAddress The type used for link addressing. template class LinksLimitReachedException : public LinksLimitReachedExceptionBase { + /// @brief Constructs exception with specific limit value. + /// @param limit The limit value that was reached. public: LinksLimitReachedException(TLinkAddress limit) : this(FormatMessage(limit)) { } + /// @brief Constructs exception with custom message and inner exception. + /// @param message Custom error message. + /// @param innerException The underlying exception. public: LinksLimitReachedException(std::string message, const std::exception& innerException) : LinksLimitReachedExceptionBase(message, innerException) { } + /// @brief Constructs exception with custom message. + /// @param message Custom error message. public: LinksLimitReachedException(std::string message) : LinksLimitReachedExceptionBase(message) { } + /// @brief Default constructor using base class default message. public: LinksLimitReachedException() : LinksLimitReachedExceptionBase(DefaultMessage) { } + /// @brief Formats error message with limit value (in Russian). + /// @param limit The limit value that was reached. + /// @return Formatted error message. private: static std::string FormatMessage(TLinkAddress limit) { return std::string("Достигнут лимит количества связей в хранилище (").append(Platform::Converters::To(limit)).append(")."); } }; } \ No newline at end of file diff --git a/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h b/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h index 37ab3c78..f4562bdf 100644 --- a/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h +++ b/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h @@ -1,11 +1,24 @@ -namespace Platform::Data::Exceptions +/// @file LinksLimitReachedExceptionBase.h +/// @brief Base class for exceptions thrown when link storage limits are exceeded. + +namespace Platform::Data::Exceptions { + /// @brief Base exception class for link storage limit violations. + /// + /// This exception is thrown when operations would exceed the maximum + /// number of links that can be stored in the system. class LinksLimitReachedExceptionBase : public std::exception { + /// @brief Default error message in Russian. public: inline static std::string DefaultMessage = "Достигнут лимит количества связей в хранилище."; + /// @brief Protected constructor with custom message and inner exception. + /// @param message Custom error message. + /// @param innerException The underlying exception. protected: LinksLimitReachedExceptionBase(std::string message, const std::exception& innerException) : base(message, innerException) { } + /// @brief Protected constructor with custom message. + /// @param message Custom error message. protected: LinksLimitReachedExceptionBase(std::string message) : base(message) { } }; } diff --git a/cpp/Platform.Data/ILinks.h b/cpp/Platform.Data/ILinks.h index d16cf014..3782f210 100644 --- a/cpp/Platform.Data/ILinks.h +++ b/cpp/Platform.Data/ILinks.h @@ -1,25 +1,63 @@ namespace Platform::Data { using namespace Platform::Interfaces; + + /// @brief Core interface for managing links in a data structure. + /// @tparam TLinksOptions Template parameter specifying the configuration options for links, + /// including address type, link type, and handler types. + /// + /// This interface defines the fundamental CRUD (Create, Read, Update, Delete) operations + /// for working with links. A link represents a connection or relationship between data elements. template struct ILinks { public: - using LinksOptionsType = TLinksOptions; - using LinkAddressType = typename LinksOptionsType::LinkAddressType; - static constexpr LinksConstants Constants = LinksOptionsType::Constants; - using LinkType = typename LinksOptionsType::LinkType; - using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; - using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + /// @brief Type alias for the links options configuration. + using LinksOptionsType = TLinksOptions; + + /// @brief Type alias for link addresses used to identify links. + using LinkAddressType = typename LinksOptionsType::LinkAddressType; + + /// @brief Constants used throughout the links system. + static constexpr LinksConstants Constants = LinksOptionsType::Constants; + + /// @brief Type alias for link data structures. + using LinkType = typename LinksOptionsType::LinkType; + + /// @brief Type alias for read operation handler functions. + using ReadHandlerType = typename LinksOptionsType::ReadHandlerType; + + /// @brief Type alias for write operation handler functions. + using WriteHandlerType = typename LinksOptionsType::WriteHandlerType; + /// @brief Counts the number of links matching the specified restriction. + /// @param restriction Vector of link addresses defining search criteria. + /// @return Number of links matching the restriction. virtual LinkAddressType Count(const std::vector& restriction) const = 0; + /// @brief Iterates through links matching the restriction and applies a handler to each. + /// @param restriction Vector of link addresses defining search criteria. + /// @param handler Function to be called for each matching link. + /// @return Result code from the iteration operation. virtual LinkAddressType Each(const std::vector& restriction, const ReadHandlerType& handler) const = 0; + /// @brief Creates a new link with the specified substitution values. + /// @param substitution Vector of link addresses specifying the new link's properties. + /// @param handler Function to handle the creation operation. + /// @return Address of the created link or result code. virtual LinkAddressType Create(const std::vector& substitution, const WriteHandlerType& handler) = 0; + /// @brief Updates existing links matching the restriction with new substitution values. + /// @param restriction Vector of link addresses defining which links to update. + /// @param substitution Vector of link addresses specifying the new values. + /// @param handler Function to handle the update operation. + /// @return Result code from the update operation. virtual LinkAddressType Update(const std::vector& restriction, const std::vector& substitution, const WriteHandlerType& handler) = 0; + /// @brief Deletes links matching the specified restriction. + /// @param restriction Vector of link addresses defining which links to delete. + /// @param handler Function to handle the deletion operation. + /// @return Result code from the delete operation. virtual LinkAddressType Delete(const std::vector& restriction, const WriteHandlerType& handler) = 0; }; } diff --git a/cpp/Platform.Data/ISynchronizedLinks.h b/cpp/Platform.Data/ISynchronizedLinks.h index 7d6b0627..dc4a58d8 100644 --- a/cpp/Platform.Data/ISynchronizedLinks.h +++ b/cpp/Platform.Data/ISynchronizedLinks.h @@ -1,11 +1,24 @@ -namespace Platform::Data +/// @file ISynchronizedLinks.h +/// @brief Thread-safe interface for link operations. + +namespace Platform::Data { + /// @brief Generic template declaration for ISynchronizedLinks. // TODO: rework Platform.Threading template class ISynchronizedLinks; + + /// @brief Interface combining thread synchronization with link operations. + /// @tparam TLinkAddress The type used for link addressing. + /// @tparam TLinks The underlying links implementation type. + /// @tparam TConstants The constants type for link operations. + /// + /// This interface provides thread-safe access to link operations by combining + /// synchronization primitives with the core ILinks interface. template class ISynchronizedLinks : public ISynchronized, ILinks where TLinks : ILinks where TConstants : LinksConstants { public: + /// @brief Empty interface body - functionality provided by base classes. } } diff --git a/cpp/Platform.Data/LinkAddress.h b/cpp/Platform.Data/LinkAddress.h index 7a4adb70..767a5e30 100644 --- a/cpp/Platform.Data/LinkAddress.h +++ b/cpp/Platform.Data/LinkAddress.h @@ -1,10 +1,21 @@ namespace Platform::Data { + /// @brief A wrapper class for link addresses that provides container-like semantics. + /// @tparam TLinkAddress The integral type used for link addressing (e.g., uint64_t, uint32_t). + /// + /// This class encapsulates a single link address and provides various conversion operators + /// and container-like interface methods. It allows treating a single address as a + /// container with one element, which simplifies generic programming with link operations. template class LinkAddress { + /// @brief The stored link address index. public: const TLinkAddress Index; + /// @brief Provides indexed access to the link address. + /// @param index The index to access (must be 0 for single-element container). + /// @return Reference to the stored Index value. + /// @throws std::out_of_range if index is not 0. public: auto operator[](std::integral auto index) const -> const TLinkAddress& { if (index == 0) @@ -17,62 +28,92 @@ } } + /// @brief Returns the size of this container (always 1). + /// @return Always returns 1 since this contains a single address. public: [[nodiscard]] constexpr auto size() const noexcept -> std::size_t { return 1; } + /// @brief Constructs a LinkAddress with the specified index value. + /// @param index The link address value to store. public: explicit LinkAddress(TLinkAddress index) : Index(index) { } + /// @brief Copy constructor for converting between different LinkAddress types. + /// @tparam OtherTLinkAddress The source LinkAddress type. + /// @param linkAddress The LinkAddress to copy from. public: template explicit LinkAddress(const LinkAddress& linkAddress) : Index(linkAddress.Index) { } + /// @brief Returns an iterator to the beginning (pointing to Index). + /// @return Pointer to the stored Index value. public: [[nodiscard]] auto begin() const noexcept -> const TLinkAddress* { return std::addressof(Index); } + /// @brief Returns an iterator to the end (one past the Index). + /// @return Pointer one position past the stored Index value. public: [[nodiscard]] auto end() const noexcept -> const TLinkAddress* { // TODO: maybe explicit write "+ 1" instead return std::addressof(Index) + size(); } + /// @brief Equality comparison operator. + /// @param other The other LinkAddress to compare with. + /// @return True if both LinkAddress objects have the same Index value. public: auto operator==(LinkAddress other) const noexcept { return Index == other.Index; } + /// @brief Explicit conversion to the underlying address type. + /// @return The stored Index value. public: explicit operator TLinkAddress() const noexcept { return Index; } - public: operator std::vector() const + /// @brief Implicit conversion to vector containing the single address. + /// @return Vector containing the Index value. + public: operator std::vector() const { return std::vector{Index}; } + /// @brief Explicit conversion to string representation. + /// @return String representation of the Index value. public: explicit operator std::string() const { return Converters::To(Index); } + /// @brief Stream output operator for printing LinkAddress objects. + /// @param stream The output stream to write to. + /// @param self The LinkAddress object to print. + /// @return Reference to the output stream. public: friend std::ostream& operator<<(std::ostream& stream, LinkAddress self) { return stream << static_cast(self); } }; + /// @brief Deduction guide for LinkAddress template parameter inference. template LinkAddress(TLinkAddress) -> LinkAddress; } +/// @brief Hash function specialization for LinkAddress to enable use in hash-based containers. +/// @tparam TLinkAddress The integral type of the link address. template struct std::hash> { + /// @brief Computes hash value for a LinkAddress object. + /// @param self The LinkAddress object to hash. + /// @return Hash value based on the Index member. std::size_t operator()(auto&& self) const { return self.Index; diff --git a/cpp/Platform.Data/LinksConstants.h b/cpp/Platform.Data/LinksConstants.h index e55b4edb..1dce4add 100644 --- a/cpp/Platform.Data/LinksConstants.h +++ b/cpp/Platform.Data/LinksConstants.h @@ -1,36 +1,55 @@ -namespace Platform::Data +/// @file LinksConstants.h +/// @brief Core constants and configuration values for the links system. + +namespace Platform::Data { + /// @brief Configuration constants for the links system. + /// @tparam TLinkAddress The integral type used for link addressing. + /// + /// This structure contains all the essential constants used throughout the links system, + /// including part indices, control flow values, and address ranges. template struct LinksConstants { + /// @brief Default index for the target part of a link. static constexpr int DefaultTargetPart = 2; + /// @brief Index for the link identifier part (typically 0). public: const TLinkAddress IndexPart{}; + /// @brief Index for the source part of a link (typically 1). public: const TLinkAddress SourcePart{}; + /// @brief Index for the target part of a link (configurable, typically 2). public: const TLinkAddress TargetPart{}; + /// @brief Value indicating continuation of operations. public: const TLinkAddress Continue{}; + /// @brief Value indicating termination of operations. public: const TLinkAddress Break{}; + /// @brief Value indicating to skip current item in operations. public: const TLinkAddress Skip{}; + /// @brief Value representing null/empty reference. public: const TLinkAddress Null{}; + /// @brief Value representing any/wildcard match in queries. public: const TLinkAddress Any{}; + /// @brief Value representing self-reference. public: const TLinkAddress Itself{}; + /// @brief Value representing error condition. public: const TLinkAddress Error{}; diff --git a/cpp/Platform.Data/LinksOptions.h b/cpp/Platform.Data/LinksOptions.h index c33f8ad9..75d83f6e 100644 --- a/cpp/Platform.Data/LinksOptions.h +++ b/cpp/Platform.Data/LinksOptions.h @@ -1,13 +1,31 @@ namespace Platform::Data { - + /// @brief Configuration template for customizing link storage and operations. + /// @tparam TLinkAddress The integral type used for link addressing (default: uint64_t). + /// @tparam VConstants Configuration constants for the links system. + /// @tparam TLink The container type used to represent links (default: std::vector). + /// @tparam TReadHandler Function type for handling read operations (default: std::function). + /// @tparam TWriteHandler Function type for handling write operations (default: std::function). + /// + /// This template struct provides type aliases and configuration options used throughout + /// the links system. It allows customization of address types, link representations, + /// and handler function signatures. template VConstants = LinksConstants{true}, typename TLink = std::vector, typename TReadHandler = std::function, typename TWriteHandler = std::function> struct LinksOptions { + /// @brief Type alias for link address values. using LinkAddressType = TLinkAddress; + + /// @brief Type alias for link data representation. using LinkType = TLink; + + /// @brief Type alias for read operation handler functions. using ReadHandlerType = TReadHandler; + + /// @brief Type alias for write operation handler functions. using WriteHandlerType = TWriteHandler; + + /// @brief Configuration constants for the links system. static constexpr LinksConstants Constants = VConstants; }; diff --git a/cpp/Platform.Data/Platform.Data.h b/cpp/Platform.Data/Platform.Data.h index b4f3215f..62d55b9d 100644 --- a/cpp/Platform.Data/Platform.Data.h +++ b/cpp/Platform.Data/Platform.Data.h @@ -1,3 +1,19 @@ +/// @file Platform.Data.h +/// @brief Main header file for the Platform.Data library. +/// +/// This header includes all the essential components of the Platform.Data library, +/// which provides a flexible framework for working with links - connections or +/// relationships between data elements. The library supports various addressing +/// schemes, link representations, and extensible operations through templates. +/// +/// Key components included: +/// - Core interfaces (ILinks) +/// - Link addressing (LinkAddress) +/// - Configuration options (LinksOptions, LinksConstants) +/// - Extension methods (ILinksExtensions) +/// - Data conversion utilities +/// - Exception handling +/// #pragma once #include diff --git a/cpp/Platform.Data/Point.h b/cpp/Platform.Data/Point.h index 85ca9882..c1eb0de9 100644 --- a/cpp/Platform.Data/Point.h +++ b/cpp/Platform.Data/Point.h @@ -1,29 +1,53 @@ -#include +/// @file Point.h +/// @brief Defines Point class for representing repeated link elements. +/// +/// A point in the context of links is a pattern where multiple positions +/// in a link contain the same value, indicating a self-reference or loop. + +#include namespace Platform::Data { namespace Internal { + /// @brief Creates a function that always returns the specified index value. + /// @param index The index value to return for any input. + /// @return Lambda function that ignores input and returns the fixed index. auto gen_always_index(auto index) { return [index](auto) { return index; }; } + /// @brief Base type for Point class using ranges view. + /// @tparam TLinkAddress The address type for the point. template using PointBase = decltype(std::views::iota(std::size_t{}, std::size_t{}) | std::views::transform(Internal::gen_always_index(TLinkAddress{}))); } + /// @brief Represents a point - a link structure where multiple positions contain the same address. + /// @tparam TLinkAddress The integral type used for addressing. + /// + /// A point is a special case of a link where one or more positions contain the same value, + /// creating self-references or loops. This class provides container-like semantics for + /// accessing repeated values. template class Point : public Internal::PointBase { + /// @brief Base class type alias. using base = Internal::PointBase; + /// @brief The repeated index value. // TODO: maybe remove or convert to property public: const TLinkAddress Index; + /// @brief The size of the point (number of repetitions). // TODO: maybe remove or convert to property public: const std::size_t Size; + /// @brief Provides indexed access to the repeated value. + /// @param index The position to access. + /// @return The Index value (same for all valid positions). + /// @throws std::out_of_range if index >= Size. public: auto operator[](std::size_t index) const -> TLinkAddress { if (index < Size) @@ -36,26 +60,44 @@ namespace Platform::Data } } + /// @brief Constructs a Point with specified index and size. + /// @param index The value to repeat at all positions. + /// @param size The number of repetitions. public: Point(TLinkAddress index, std::size_t size) : Index(index), Size(size), base(std::views::iota(std::size_t(0), size), Internal::gen_always_index(index)) { } + /// @brief Equality comparison with LinkAddress. + /// @param other The LinkAddress to compare with. + /// @return True if Index values are equal. public: auto operator==(const LinkAddress &other) const noexcept { return Index == other.Index; } + /// @brief Explicit conversion to the underlying address type. + /// @return The Index value. public: explicit operator TLinkAddress() const noexcept { return Index; } + /// @brief Explicit conversion to string representation. + /// @return String representation of the Index value. public: explicit operator std::string() const { return Converters::To(Index).data(); } + /// @brief Stream output operator. + /// @param stream The output stream. + /// @param self The Point object to output. + /// @return Reference to the output stream. public: friend std::ostream& operator<<(std::ostream& stream, const Point& self) { return stream << static_cast(self); } }; + /// @brief Deduction guide for Point template parameter inference. template Point(TLinkAddress, Args...) -> Point; + /// @brief Checks if a link is a full point without validation (all elements are the same). + /// @param link The link to check. + /// @return True if all elements after the first are equal to the first element. static bool IsFullPointUnchecked(Interfaces::CEnumerable auto&& link) requires std::integral::Item> { @@ -64,6 +106,10 @@ namespace Platform::Data return std::ranges::all_of(iter + 1, end, [&iter](auto&& item) {return item == *iter; }); } + /// @brief Checks if a link is a full point with validation (all elements are the same). + /// @param link The link to check. + /// @return True if all elements are equal and link size is valid. + /// @throws ArgumentOutOfRangeException if link size is less than 2. static bool IsFullPoint(Interfaces::CEnumerable auto&& link) requires std::integral::Item> { @@ -74,12 +120,18 @@ namespace Platform::Data return IsFullPointUnchecked(link); } + /// @brief Checks if parameters form a full point (all values are the same). + /// @param params Variable arguments representing link elements. + /// @return True if all parameters are equal. static bool IsFullPoint(std::integral auto... params) { std::common_type_t link[] = { params... }; return IsFullPoint(link); } + /// @brief Checks if a link is a partial point without validation (some elements are the same). + /// @param link The link to check. + /// @return True if any element after the first equals the first element. static bool IsPartialPointUnchecked(Interfaces::CEnumerable auto&& link) requires std::integral::Item> { @@ -89,6 +141,10 @@ namespace Platform::Data return std::ranges::any_of(iter + 1, end, [&iter](auto&& item) { return item == *iter; }); } + /// @brief Checks if a link is a partial point with validation (some elements are the same). + /// @param link The link to check. + /// @return True if at least one element equals the first element and link size is valid. + /// @throws ArgumentOutOfRangeException if link size is less than 2. static bool IsPartialPoint(Interfaces::CEnumerable auto&& link) { using namespace Platform::Ranges; @@ -98,6 +154,9 @@ namespace Platform::Data return IsPartialPointUnchecked(link); } + /// @brief Checks if parameters form a partial point (some values are the same). + /// @param params Variable arguments representing link elements. + /// @return True if any parameter equals the first parameter. // TODO: we don't have args... to array-like converter static bool IsPartialPoint(std::integral auto... params) { @@ -108,9 +167,14 @@ namespace Platform::Data } +/// @brief Hash function specialization for Point to enable use in hash-based containers. +/// @tparam TLinkAddress The address type of the Point. template struct std::hash> { + /// @brief Computes hash value for a Point object. + /// @param self The Point object to hash. + /// @return Hash value based on the Index member. std::size_t operator()(const Platform::Data::Point& self) const noexcept { return self.Index; diff --git a/cpp/Platform.Data/WriteHandlerState.h b/cpp/Platform.Data/WriteHandlerState.h index ab1c8e08..c62fa794 100644 --- a/cpp/Platform.Data/WriteHandlerState.h +++ b/cpp/Platform.Data/WriteHandlerState.h @@ -1,16 +1,38 @@ namespace Platform::Data { using namespace Platform::Interfaces; + + /// @brief Manages state and control flow for write operation handlers. + /// @tparam TStorage The storage type that defines LinkAddressType and other related types. + /// + /// This class provides a stateful wrapper around write operation handlers, allowing + /// for early termination (break) conditions and result accumulation. It's commonly + /// used in operations that process multiple links and need to support interruption. template struct WriteHandlerState { + /// @brief The address value that signals a break/stop condition. typename TStorage::LinkAddressType Break; + + /// @brief The current result value, initialized to 0. typename TStorage::LinkAddressType Result = 0; + + /// @brief The underlying handler function for write operations. std::function, std::vector)> Handler; + /// @brief Constructs a WriteHandlerState with specified control values and handler. + /// @param $continue The value representing continue/success state. + /// @param $break The value that triggers break/stop condition. + /// @param handler The function to handle write operations. WriteHandlerState(typename TStorage::LinkAddressType $continue, typename TStorage::LinkAddressType $break, auto&& handler) : Result{$continue}, Break{$break}, Handler{handler} {} + /// @brief Applies the result and checks for break condition. + /// @param result The result value to process. + /// @return The current Result value. + /// + /// If the result equals Break, sets Result to Break and nullifies Handler + /// to prevent further processing. typename TStorage::LinkAddressType Apply(typename TStorage::LinkAddressType result) { if (Break == result) @@ -21,6 +43,12 @@ namespace Platform::Data return Result; } + /// @brief Handles arguments by invoking the stored handler function. + /// @param args Arguments to forward to the handler function. + /// @return Result value after applying the handler or current Result if handler is null. + /// + /// If Handler is null (due to break condition), returns current Result. + /// Otherwise, invokes Handler with forwarded arguments and applies the result. typename TStorage::LinkAddressType Handle(auto&& ...args) { if(nullptr == Handler)