diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..688e2c54 --- /dev/null +++ b/.clang-format @@ -0,0 +1,55 @@ +# Based on observed code style in the repository +BasedOnStyle: LLVM + +# Indentation +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +ContinuationIndentWidth: 4 + +# Braces +BreakBeforeBraces: Allman +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortCaseLabelsOnASingleLine: false + +# Spacing +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceAfterCStyleCast: true +SpaceBeforeAssignmentOperators: true +SpaceAfterTemplateKeyword: false + +# Alignment +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +PointerAlignment: Left +ReferenceAlignment: Left + +# Line length and wrapping +ColumnLimit: 120 +AllowAllParametersOfDeclarationOnNextLine: true +AllowAllArgumentsOnNextLine: true +BinPackParameters: false +BinPackArguments: false + +# Includes +SortIncludes: true +IncludeBlocks: Preserve + +# Namespaces +NamespaceIndentation: None +CompactNamespaces: false + +# Access modifiers +AccessModifierOffset: -4 + +# Other formatting +ReflowComments: true +FixNamespaceComments: true +SpaceBeforeRangeBasedForLoopColon: true +Standard: c++20 \ No newline at end of file diff --git a/.github/workflows/cpp-format-check.yml b/.github/workflows/cpp-format-check.yml new file mode 100644 index 00000000..8b741632 --- /dev/null +++ b/.github/workflows/cpp-format-check.yml @@ -0,0 +1,52 @@ +name: C++ Format Check + +on: + pull_request: + branches: + - main + - master + paths: + - 'cpp/**/*.h' + - 'cpp/**/*.hpp' + - 'cpp/**/*.cpp' + - 'cpp/**/*.cc' + - 'cpp/**/*.c' + - '.clang-format' + - 'format-check.sh' + +jobs: + format-check: + name: Check C++ Code Formatting + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install clang-format + run: | + sudo apt-get update + sudo apt-get install -y clang-format + + - name: Verify clang-format version + run: clang-format --version + + - name: Run format check + run: | + chmod +x ./format-check.sh + ./format-check.sh + + - name: Format check failed + if: failure() + run: | + echo "" + echo "❌ C++ code formatting check failed!" + echo "" + echo "Some files are not properly formatted according to .clang-format" + echo "" + echo "To fix formatting issues:" + echo "1. Run: ./format-apply.sh" + echo "2. Commit the changes" + echo "3. Push to update your PR" + echo "" + exit 1 \ No newline at end of file diff --git a/README.md b/README.md index d9b086f0..e95b5ae5 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,25 @@ Interface [ILinks\](https://linksplatform.github.io/D * [Platform.Numbers](https://github.com/linksplatform/Numbers) * [Platform.Setters](https://github.com/linksplatform/Setters) +## C++ Code Formatting + +This repository uses [clang-format](https://clang.llvm.org/docs/ClangFormat.html) to ensure consistent C++ code formatting. The formatting rules are defined in `.clang-format`. + +### Format Commands + +Similar to Java's `./gradlew spotlessCheck` and `./gradlew spotlessApply`, we provide equivalent scripts for C++: + +- **Check formatting**: `./format-check.sh` - Checks if all C++ files are properly formatted +- **Apply formatting**: `./format-apply.sh` - Formats all C++ files according to the style guide + +### CI Integration + +Pull requests automatically check C++ code formatting using GitHub Actions. If formatting issues are found, the PR will be marked as failed until the code is properly formatted. + +To fix formatting issues in your PR: +1. Run `./format-apply.sh` to format your code +2. Commit and push the changes + ## Dependent libraries * [Platform.Data.Doublets](https://github.com/linksplatform/Data.Doublets) * [Platform.Data.Triplets](https://github.com/linksplatform/Data.Triplets) diff --git a/cpp/Platform.Data.Tests/AllTests.cpp b/cpp/Platform.Data.Tests/AllTests.cpp index 5b3e8ed0..544009a9 100644 --- a/cpp/Platform.Data.Tests/AllTests.cpp +++ b/cpp/Platform.Data.Tests/AllTests.cpp @@ -2,6 +2,6 @@ #include #include "HybridTests.cpp" -#include "LinksConstantsTests.cpp" #include "ILinksTests.cpp" +#include "LinksConstantsTests.cpp" #include "PointTests.cpp" diff --git a/cpp/Platform.Data.Tests/HybridTests.cpp b/cpp/Platform.Data.Tests/HybridTests.cpp index 74ac2bdd..98cba11f 100644 --- a/cpp/Platform.Data.Tests/HybridTests.cpp +++ b/cpp/Platform.Data.Tests/HybridTests.cpp @@ -1,10 +1,10 @@ namespace Platform::Data::Tests { - TEST(HybridTests, ObjectConstructorTest) - { - ASSERT_EQ(0, Hybrid(std::uint8_t{128}).AbsoluteValue()); - ASSERT_EQ(1, Hybrid(static_cast(-1)).AbsoluteValue()); - ASSERT_EQ(0, Hybrid(std::uint8_t{0}).AbsoluteValue()); - ASSERT_EQ(1, Hybrid(std::uint8_t{1}).AbsoluteValue()); - }; -} +TEST(HybridTests, ObjectConstructorTest) +{ + ASSERT_EQ(0, Hybrid(std::uint8_t{128}).AbsoluteValue()); + ASSERT_EQ(1, Hybrid(static_cast(-1)).AbsoluteValue()); + ASSERT_EQ(0, Hybrid(std::uint8_t{0}).AbsoluteValue()); + ASSERT_EQ(1, Hybrid(std::uint8_t{1}).AbsoluteValue()); +}; +} // namespace Platform::Data::Tests diff --git a/cpp/Platform.Data.Tests/ILinksTests.cpp b/cpp/Platform.Data.Tests/ILinksTests.cpp index 99159b54..fdad6c9d 100644 --- a/cpp/Platform.Data.Tests/ILinksTests.cpp +++ b/cpp/Platform.Data.Tests/ILinksTests.cpp @@ -1,40 +1,61 @@ namespace Platform::Data::Tests { - template VConstants = LinksConstants{true}, typename TLink = std::vector, typename TReadHandler = std::function, typename TWriteHandler = std::function> - struct Links : public ILinks> - { - using base = ILinks>; - using typename base::LinkAddressType; - using typename base::LinkType; - using typename base::WriteHandlerType; - using typename base::ReadHandlerType; - using base::Constants; - - LinkAddressType Count(const std::vector& restriction) const override { return 0; }; +template VConstants = LinksConstants{true}, + typename TLink = std::vector, + typename TReadHandler = std::function, + typename TWriteHandler = std::function> +struct Links : public ILinks> +{ + using base = ILinks>; + using base::Constants; + using typename base::LinkAddressType; + using typename base::LinkType; + using typename base::ReadHandlerType; + using typename base::WriteHandlerType; - LinkAddressType Each(const std::vector& restriction, const ReadHandlerType& handler) const override { return 0; }; + LinkAddressType Count(const std::vector& restriction) const override + { + return 0; + }; - LinkAddressType Create(const std::vector& restriction, const WriteHandlerType& handler) override { return 0; }; + LinkAddressType Each(const std::vector& restriction, const ReadHandlerType& handler) const override + { + return 0; + }; - LinkAddressType Update(const std::vector& restriction, const std::vector& substitution, const WriteHandlerType& handler) override { return 0; }; + LinkAddressType Create(const std::vector& restriction, const WriteHandlerType& handler) override + { + return 0; + }; - LinkAddressType Delete(const std::vector& restriction, const WriteHandlerType& handler) override { return 0; }; + LinkAddressType Update(const std::vector& restriction, + const std::vector& substitution, + const WriteHandlerType& handler) override + { + return 0; }; - TEST(ILinksDeriverTest, ConstructorAndMethodsTest) + + LinkAddressType Delete(const std::vector& restriction, const WriteHandlerType& handler) override { - using TLinkAddress = uint64_t; - using TLink = std::vector; - using TWriteHandler = std::function; - using TReadHandler = std::function; - Links storage{}; - const Links const_links {storage}; - const TLinkAddress linkAddress {1}; - Create(storage, linkAddress); - Update(storage, TLink{1}, TLink{1, 1}); - storage.Count(TLink{1}); - const_links.Count(TLink{1}); - storage.Each(TLink{1}, [](const TLink& link){ return 1; }); - const_links.Each(TLink{1}, [](const TLink& link){ return 1; }); - Delete(storage, TLink{1}); - } + return 0; + }; +}; +TEST(ILinksDeriverTest, ConstructorAndMethodsTest) +{ + using TLinkAddress = uint64_t; + using TLink = std::vector; + using TWriteHandler = std::function; + using TReadHandler = std::function; + Links storage{}; + const Links const_links{storage}; + const TLinkAddress linkAddress{1}; + Create(storage, linkAddress); + Update(storage, TLink{1}, TLink{1, 1}); + storage.Count(TLink{1}); + const_links.Count(TLink{1}); + storage.Each(TLink{1}, [](const TLink& link) { return 1; }); + const_links.Each(TLink{1}, [](const TLink& link) { return 1; }); + Delete(storage, TLink{1}); } +} // namespace Platform::Data::Tests diff --git a/cpp/Platform.Data.Tests/LinksConstantsTests.cpp b/cpp/Platform.Data.Tests/LinksConstantsTests.cpp index d2c0fb6a..7ac28c79 100644 --- a/cpp/Platform.Data.Tests/LinksConstantsTests.cpp +++ b/cpp/Platform.Data.Tests/LinksConstantsTests.cpp @@ -1,39 +1,40 @@ namespace Platform::Data::Tests { - TEST(LinksConstantsTests, ConstructorTest) - { - using namespace Platform::Data; +TEST(LinksConstantsTests, ConstructorTest) +{ + using namespace Platform::Data; - auto constants = LinksConstants(true); - ASSERT_EQ(Hybrid::ExternalZero, constants.ExternalReferencesRange.Minimum); - ASSERT_EQ(std::numeric_limits::max(), constants.ExternalReferencesRange.Maximum); - } + auto constants = LinksConstants(true); + ASSERT_EQ(Hybrid::ExternalZero, constants.ExternalReferencesRange.Minimum); + ASSERT_EQ(std::numeric_limits::max(), constants.ExternalReferencesRange.Maximum); +} - template> - static void TestExternalReferences() - { - using namespace Platform::Data; - using namespace Platform::Ranges; +template> +static void TestExternalReferences() +{ + using namespace Platform::Data; + using namespace Platform::Ranges; - constexpr TUnsigned unsingedOne = 1; - constexpr TUnsigned half = std::numeric_limits::max(); - constexpr LinksConstants constants {Range{unsingedOne, half}, Range{TUnsigned(half + unsingedOne), std::numeric_limits::max()}}; + constexpr TUnsigned unsingedOne = 1; + constexpr TUnsigned half = std::numeric_limits::max(); + constexpr LinksConstants constants{ + Range{unsingedOne, half}, Range{TUnsigned(half + unsingedOne), std::numeric_limits::max()}}; - auto minimum = Hybrid(0, true); - auto maximum = Hybrid(half, true); - ASSERT_TRUE((IsExternalReference(minimum.Value))); - ASSERT_TRUE(minimum.IsExternal()); - ASSERT_FALSE(minimum.IsInternal()); - ASSERT_TRUE((IsExternalReference(maximum.Value))); - ASSERT_TRUE(maximum.IsExternal()); - ASSERT_FALSE(maximum.IsInternal()); - } + auto minimum = Hybrid(0, true); + auto maximum = Hybrid(half, true); + ASSERT_TRUE((IsExternalReference(minimum.Value))); + ASSERT_TRUE(minimum.IsExternal()); + ASSERT_FALSE(minimum.IsInternal()); + ASSERT_TRUE((IsExternalReference(maximum.Value))); + ASSERT_TRUE(maximum.IsExternal()); + ASSERT_FALSE(maximum.IsInternal()); +} - TEST(LinksConstantsTests, ExternalReferencesTest) - { - TestExternalReferences(); - TestExternalReferences(); - TestExternalReferences(); - TestExternalReferences(); - } +TEST(LinksConstantsTests, ExternalReferencesTest) +{ + TestExternalReferences(); + TestExternalReferences(); + TestExternalReferences(); + TestExternalReferences(); } +} // namespace Platform::Data::Tests diff --git a/cpp/Platform.Data.Tests/PointTests.cpp b/cpp/Platform.Data.Tests/PointTests.cpp index 114c08ed..caec1878 100644 --- a/cpp/Platform.Data.Tests/PointTests.cpp +++ b/cpp/Platform.Data.Tests/PointTests.cpp @@ -1,16 +1,16 @@ namespace Platform::Data::Tests { - TEST(PointTests, IsPartialPointTest) - { - ASSERT_TRUE(IsPartialPoint(1, 1, 2)); - ASSERT_TRUE(IsPartialPoint(1, 2, 1)); - ASSERT_TRUE(IsPartialPoint(1, 1, 1)); - ASSERT_FALSE(IsPartialPoint(1, 2, 3)); - }; - TEST(PointTests, IsFullPointTest) - { - ASSERT_TRUE(IsFullPoint(1, 1, 1)); - ASSERT_FALSE(IsFullPoint(1, 2, 1)); - ASSERT_FALSE(IsFullPoint(1, 1, 2)); - }; -} +TEST(PointTests, IsPartialPointTest) +{ + ASSERT_TRUE(IsPartialPoint(1, 1, 2)); + ASSERT_TRUE(IsPartialPoint(1, 2, 1)); + ASSERT_TRUE(IsPartialPoint(1, 1, 1)); + ASSERT_FALSE(IsPartialPoint(1, 2, 3)); +}; +TEST(PointTests, IsFullPointTest) +{ + ASSERT_TRUE(IsFullPoint(1, 1, 1)); + ASSERT_FALSE(IsFullPoint(1, 2, 1)); + ASSERT_FALSE(IsFullPoint(1, 1, 2)); +}; +} // namespace Platform::Data::Tests diff --git a/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h b/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h index 352f82da..3919730c 100644 --- a/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h +++ b/cpp/Platform.Data/Exceptions/ArgumentLinkDoesNotExistsException.h @@ -1,20 +1,51 @@ namespace Platform::Data::Exceptions { - template class ArgumentLinkDoesNotExistsException; - template class ArgumentLinkDoesNotExistsException : public std::invalid_argument +template class ArgumentLinkDoesNotExistsException; +template class ArgumentLinkDoesNotExistsException : public std::invalid_argument +{ +public: + ArgumentLinkDoesNotExistsException(TLinkAddress link, std::string argumentName) + : std::invalid_argument(FormatMessage(link, argumentName), argumentName) { - public: ArgumentLinkDoesNotExistsException(TLinkAddress link, std::string argumentName) : std::invalid_argument(FormatMessage(link, argumentName), argumentName) { } + } - public: ArgumentLinkDoesNotExistsException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) { } +public: + ArgumentLinkDoesNotExistsException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) + { + } - public: ArgumentLinkDoesNotExistsException(std::string message, const std::exception& innerException) : std::invalid_argument(message, innerException) { } +public: + ArgumentLinkDoesNotExistsException(std::string message, const std::exception& innerException) + : std::invalid_argument(message, innerException) + { + } - public: ArgumentLinkDoesNotExistsException(std::string message) : std::invalid_argument(message) { } +public: + ArgumentLinkDoesNotExistsException(std::string message) : std::invalid_argument(message) + { + } - public: ArgumentLinkDoesNotExistsException() { } +public: + ArgumentLinkDoesNotExistsException() + { + } - private: static std::string FormatMessage(TLinkAddress link, std::string argumentName) { return std::string("Связь [").append(Platform::Converters::To(link)).append("] переданная в аргумент [").append(argumentName).append("] не существует."); } +private: + static std::string FormatMessage(TLinkAddress link, std::string argumentName) + { + return std::string("Связь [") + .append(Platform::Converters::To(link)) + .append("] переданная в аргумент [") + .append(argumentName) + .append("] не существует."); + } - private: static std::string FormatMessage(TLinkAddress link) { return std::string("Связь [").append(Platform::Converters::To(link)).append("] переданная в качестве аргумента не существует."); } - }; -} \ No newline at end of file +private: + static std::string FormatMessage(TLinkAddress link) + { + return std::string("Связь [") + .append(Platform::Converters::To(link)) + .append("] переданная в качестве аргумента не существует."); + } +}; +} // namespace Platform::Data::Exceptions \ No newline at end of file diff --git a/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h b/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h index 06f47c1e..11316235 100644 --- a/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h +++ b/cpp/Platform.Data/Exceptions/ArgumentLinkHasDependenciesException.h @@ -1,20 +1,52 @@ namespace Platform::Data::Exceptions { - template class ArgumentLinkHasDependenciesException; - template class ArgumentLinkHasDependenciesException : public std::invalid_argument +template class ArgumentLinkHasDependenciesException; +template class ArgumentLinkHasDependenciesException : public std::invalid_argument +{ +public: + ArgumentLinkHasDependenciesException(TLinkAddress link, std::string paramName) + : std::invalid_argument(FormatMessage(link, paramName), paramName) { - public: ArgumentLinkHasDependenciesException(TLinkAddress link, std::string paramName) : std::invalid_argument(FormatMessage(link, paramName), paramName) { } + } - public: ArgumentLinkHasDependenciesException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) { } +public: + ArgumentLinkHasDependenciesException(TLinkAddress link) : std::invalid_argument(FormatMessage(link)) + { + } - public: ArgumentLinkHasDependenciesException(std::string message, const std::exception& innerException) : std::invalid_argument(message, innerException) { } +public: + ArgumentLinkHasDependenciesException(std::string message, const std::exception& innerException) + : std::invalid_argument(message, innerException) + { + } - public: ArgumentLinkHasDependenciesException(std::string message) : std::invalid_argument(message) { } +public: + ArgumentLinkHasDependenciesException(std::string message) : std::invalid_argument(message) + { + } - public: ArgumentLinkHasDependenciesException() { } +public: + ArgumentLinkHasDependenciesException() + { + } - private: static std::string FormatMessage(TLinkAddress link, std::string paramName) { return std::string("У связи [").append(Platform::Converters::To(link)).append("] переданной в аргумент [").append(paramName).append("] присутствуют зависимости, которые препятствуют изменению её внутренней структуры."); } +private: + static std::string FormatMessage(TLinkAddress link, std::string paramName) + { + return std::string("У связи [") + .append(Platform::Converters::To(link)) + .append("] переданной в аргумент [") + .append(paramName) + .append("] присутствуют зависимости, которые препятствуют изменению её внутренней структуры."); + } - private: static std::string FormatMessage(TLinkAddress link) { return std::string("У связи [").append(Platform::Converters::To(link)).append("] переданной в качестве аргумента присутствуют зависимости, которые препятствуют изменению её внутренней структуры."); } - }; -} \ No newline at end of file +private: + static std::string FormatMessage(TLinkAddress link) + { + return std::string("У связи [") + .append(Platform::Converters::To(link)) + .append("] переданной в качестве аргумента присутствуют зависимости, которые препятствуют изменению её " + "внутренней структуры."); + } +}; +} // namespace Platform::Data::Exceptions \ No newline at end of file diff --git a/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h b/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h index 5b2c69d5..a0aa3855 100644 --- a/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h +++ b/cpp/Platform.Data/Exceptions/LinkWithSameValueAlreadyExistsException.h @@ -1,13 +1,24 @@ namespace Platform::Data::Exceptions { - class LinkWithSameValueAlreadyExistsException : public std::exception - { - public: inline static std::string DefaultMessage = "Связь с таким же значением уже существует."; +class LinkWithSameValueAlreadyExistsException : public std::exception +{ +public: + inline static std::string DefaultMessage = "Связь с таким же значением уже существует."; - public: LinkWithSameValueAlreadyExistsException(std::string message, const std::exception& innerException) : base(message, innerException) { } +public: + LinkWithSameValueAlreadyExistsException(std::string message, const std::exception& innerException) + : base(message, innerException) + { + } - public: LinkWithSameValueAlreadyExistsException(std::string message) : base(message) { } +public: + LinkWithSameValueAlreadyExistsException(std::string message) : base(message) + { + } - public: LinkWithSameValueAlreadyExistsException() : base(DefaultMessage) { } - }; -} +public: + LinkWithSameValueAlreadyExistsException() : base(DefaultMessage) + { + } +}; +} // namespace Platform::Data::Exceptions diff --git a/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h b/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h index 521cb35c..e65dec06 100644 --- a/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h +++ b/cpp/Platform.Data/Exceptions/LinksLimitReachedException.h @@ -1,16 +1,35 @@ namespace Platform::Data::Exceptions { - template class LinksLimitReachedException; - template class LinksLimitReachedException : public LinksLimitReachedExceptionBase +template class LinksLimitReachedException; +template class LinksLimitReachedException : public LinksLimitReachedExceptionBase +{ +public: + LinksLimitReachedException(TLinkAddress limit) : this(FormatMessage(limit)) { - public: LinksLimitReachedException(TLinkAddress limit) : this(FormatMessage(limit)) { } + } - public: LinksLimitReachedException(std::string message, const std::exception& innerException) : LinksLimitReachedExceptionBase(message, innerException) { } +public: + LinksLimitReachedException(std::string message, const std::exception& innerException) + : LinksLimitReachedExceptionBase(message, innerException) + { + } - public: LinksLimitReachedException(std::string message) : LinksLimitReachedExceptionBase(message) { } +public: + LinksLimitReachedException(std::string message) : LinksLimitReachedExceptionBase(message) + { + } - public: LinksLimitReachedException() : LinksLimitReachedExceptionBase(DefaultMessage) { } +public: + LinksLimitReachedException() : LinksLimitReachedExceptionBase(DefaultMessage) + { + } - private: static std::string FormatMessage(TLinkAddress limit) { return std::string("Достигнут лимит количества связей в хранилище (").append(Platform::Converters::To(limit)).append(")."); } - }; -} \ No newline at end of file +private: + static std::string FormatMessage(TLinkAddress limit) + { + return std::string("Достигнут лимит количества связей в хранилище (") + .append(Platform::Converters::To(limit)) + .append(")."); + } +}; +} // namespace Platform::Data::Exceptions \ No newline at end of file diff --git a/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h b/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h index 37ab3c78..a2771e06 100644 --- a/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h +++ b/cpp/Platform.Data/Exceptions/LinksLimitReachedExceptionBase.h @@ -1,11 +1,19 @@ namespace Platform::Data::Exceptions { - class LinksLimitReachedExceptionBase : public std::exception - { - public: inline static std::string DefaultMessage = "Достигнут лимит количества связей в хранилище."; +class LinksLimitReachedExceptionBase : public std::exception +{ +public: + inline static std::string DefaultMessage = "Достигнут лимит количества связей в хранилище."; - protected: LinksLimitReachedExceptionBase(std::string message, const std::exception& innerException) : base(message, innerException) { } +protected: + LinksLimitReachedExceptionBase(std::string message, const std::exception& innerException) + : base(message, innerException) + { + } - protected: LinksLimitReachedExceptionBase(std::string message) : base(message) { } - }; -} +protected: + LinksLimitReachedExceptionBase(std::string message) : base(message) + { + } +}; +} // namespace Platform::Data::Exceptions diff --git a/cpp/Platform.Data/Hybrid.h b/cpp/Platform.Data/Hybrid.h index 0c3fa9d3..ad24ee64 100644 --- a/cpp/Platform.Data/Hybrid.h +++ b/cpp/Platform.Data/Hybrid.h @@ -1,85 +1,115 @@ namespace Platform::Data { - namespace Internal - { - constexpr auto smart_to_signed(std::integral auto value) noexcept - { - using raw_type = decltype(value); - return static_cast>(value); - } - } +namespace Internal +{ +constexpr auto smart_to_signed(std::integral auto value) noexcept +{ + using raw_type = decltype(value); + return static_cast>(value); +} +} // namespace Internal - template - class Hybrid - { - public: static constexpr TLinkAddress HalfOfNumberValuesRange = std::numeric_limits::max() / 2; - public: static constexpr TLinkAddress ExternalZero = static_cast(HalfOfNumberValuesRange + 1); +template class Hybrid +{ +public: + static constexpr TLinkAddress HalfOfNumberValuesRange = std::numeric_limits::max() / 2; - public: const TLinkAddress Value = 0; +public: + static constexpr TLinkAddress ExternalZero = static_cast(HalfOfNumberValuesRange + 1); - public: [[nodiscard]] bool IsNothing() const noexcept - { - return (Value == ExternalZero) || (SignedValue() == 0); - } +public: + const TLinkAddress Value = 0; - public: [[nodiscard]] bool IsInternal() const noexcept - { - return SignedValue() > 0; - } +public: + [[nodiscard]] bool IsNothing() const noexcept + { + return (Value == ExternalZero) || (SignedValue() == 0); + } - public: [[nodiscard]] bool IsExternal() const noexcept - { - return (Value == ExternalZero) || (SignedValue() < 0); - } +public: + [[nodiscard]] bool IsInternal() const noexcept + { + return SignedValue() > 0; + } - public: [[nodiscard]] auto SignedValue() const noexcept -> decltype(Internal::smart_to_signed(Value)) - { - return Internal::smart_to_signed(Value); - } +public: + [[nodiscard]] bool IsExternal() const noexcept + { + return (Value == ExternalZero) || (SignedValue() < 0); + } - public: [[nodiscard]] TLinkAddress AbsoluteValue() const noexcept - { - return (Value == ExternalZero) ? 0 : std::abs(SignedValue()); - } +public: + [[nodiscard]] auto SignedValue() const noexcept -> decltype(Internal::smart_to_signed(Value)) + { + return Internal::smart_to_signed(Value); + } - public: explicit Hybrid(TLinkAddress value) noexcept : Value(value) { } +public: + [[nodiscard]] TLinkAddress AbsoluteValue() const noexcept + { + return (Value == ExternalZero) ? 0 : std::abs(SignedValue()); + } - public: Hybrid(TLinkAddress value, bool isExternal) noexcept : Value(external_constructor(value, isExternal)) { } +public: + explicit Hybrid(TLinkAddress value) noexcept : Value(value) + { + } - public: template explicit operator TOutAddress() const noexcept { return static_cast(Value); } +public: + Hybrid(TLinkAddress value, bool isExternal) noexcept : Value(external_constructor(value, isExternal)) + { + } - public: explicit operator std::string() const { return IsExternal() ? std::string("<").append(Converters::To(AbsoluteValue())).append(1, '>') : Converters::To(Value); } +public: + template explicit operator TOutAddress() const noexcept + { + return static_cast(Value); + } + +public: + explicit operator std::string() const + { + return IsExternal() ? std::string("<").append(Converters::To(AbsoluteValue())).append(1, '>') + : Converters::To(Value); + } - public: friend std::ostream& operator<<(std::ostream& stream, const Hybrid& self) { return stream << static_cast(self); } +public: + friend std::ostream& operator<<(std::ostream& stream, const Hybrid& self) + { + return stream << static_cast(self); + } - public: constexpr auto operator==(const Hybrid& other) const noexcept { return Value == other.Value; } +public: + constexpr auto operator==(const Hybrid& other) const noexcept + { + return Value == other.Value; + } - private: static TLinkAddress external_constructor(TLinkAddress value, bool isExternal) noexcept +private: + static TLinkAddress external_constructor(TLinkAddress value, bool isExternal) noexcept + { + if (value == 0 && isExternal) { - if (value == 0 && isExternal) - { - return ExternalZero; - } - else - { - auto absolute = std::abs(Internal::smart_to_signed(value)); // std::abs is not overloaded for unsigned types - return (isExternal) ? -absolute : absolute; - } + return ExternalZero; } - }; + else + { + auto absolute = std::abs(Internal::smart_to_signed(value)); // std::abs is not overloaded for unsigned types + return (isExternal) ? -absolute : absolute; + } + } +}; - template - Hybrid(TLinkAddress, Args...) -> Hybrid; -} +template Hybrid(TLinkAddress, Args...) -> Hybrid; +} // namespace Platform::Data namespace std { - template - struct hash> +template struct hash> +{ + std::size_t operator()(auto&& self) const { - std::size_t operator()(auto&& self) const - { - return self.Value; - } - }; -} + return self.Value; + } +}; +} // namespace std diff --git a/cpp/Platform.Data/ILinks.h b/cpp/Platform.Data/ILinks.h index d16cf014..fda20391 100644 --- a/cpp/Platform.Data/ILinks.h +++ b/cpp/Platform.Data/ILinks.h @@ -1,25 +1,29 @@ namespace Platform::Data { - using namespace Platform::Interfaces; - 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; +using namespace Platform::Interfaces; +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; - virtual LinkAddressType Count(const std::vector& restriction) const = 0; + virtual LinkAddressType Count(const std::vector& restriction) const = 0; - virtual LinkAddressType Each(const std::vector& restriction, const ReadHandlerType& handler) const = 0; + virtual LinkAddressType Each(const std::vector& restriction, + const ReadHandlerType& handler) const = 0; - virtual LinkAddressType Create(const std::vector& substitution, const WriteHandlerType& handler) = 0; + virtual LinkAddressType Create(const std::vector& substitution, + const WriteHandlerType& handler) = 0; - virtual LinkAddressType Update(const std::vector& restriction, const std::vector& substitution, const WriteHandlerType& handler) = 0; + virtual LinkAddressType Update(const std::vector& restriction, + const std::vector& substitution, + const WriteHandlerType& handler) = 0; - virtual LinkAddressType Delete(const std::vector& restriction, const WriteHandlerType& handler) = 0; - }; -} + virtual LinkAddressType Delete(const std::vector& restriction, + const WriteHandlerType& handler) = 0; +}; +} // namespace Platform::Data diff --git a/cpp/Platform.Data/ILinksExtensions.h b/cpp/Platform.Data/ILinksExtensions.h index eda95168..3e3914c0 100644 --- a/cpp/Platform.Data/ILinksExtensions.h +++ b/cpp/Platform.Data/ILinksExtensions.h @@ -1,135 +1,173 @@ namespace Platform::Data { - using namespace Platform::Interfaces; - template - static typename TStorage::LinkAddressType Create(TStorage& storage, const typename TStorage::LinkType& substitution) - { - auto $continue { storage.Constants.Continue }; - typename TStorage::LinkAddressType createdLinkAddress; - DIRECT_METHOD_CALL(TStorage, storage, Create, substitution, [&createdLinkAddress, $continue] (const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) - { - createdLinkAddress = after[0]; - return $continue; - }); - return createdLinkAddress; - } - - template - static typename TStorage::LinkAddressType Create(TStorage& storage, std::convertible_to auto ...substitutionPack) - { - typename TStorage::LinkType substitution { static_cast(substitutionPack)... }; - auto $continue { storage.Constants.Continue }; - typename TStorage::LinkAddressType createdLinkAddress; - DIRECT_METHOD_CALL(TStorage, storage, Create, substitution, [&createdLinkAddress, $continue] (const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) +using namespace Platform::Interfaces; +template +static typename TStorage::LinkAddressType Create(TStorage& storage, const typename TStorage::LinkType& substitution) +{ + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType createdLinkAddress; + DIRECT_METHOD_CALL(TStorage, + storage, + Create, + substitution, + [&createdLinkAddress, $continue](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) { createdLinkAddress = after[0]; return $continue; }); - return createdLinkAddress; - } - - template - static typename TStorage::LinkAddressType Update(TStorage& storage, const typename TStorage::LinkType& restriction, const typename TStorage::LinkType& substitution) - { - auto $continue{storage.Constants.Continue}; - typename TStorage::LinkAddressType updatedLinkAddress; - DIRECT_METHOD_CALL(TStorage, storage, Update, restriction, substitution, [&updatedLinkAddress, $continue] (const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) - { - updatedLinkAddress = after[0]; - return $continue; - }); - return updatedLinkAddress; - } - - template - static typename TStorage::LinkAddressType Delete(TStorage& storage, const typename TStorage::LinkType& restriction) - { - auto $continue{storage.Constants.Continue}; - typename TStorage::LinkAddressType deletedLinkAddress; - DIRECT_METHOD_CALL(TStorage, storage, Delete, restriction, [&deletedLinkAddress, $continue] (const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) - { - deletedLinkAddress = before[0]; - return $continue; - }); - return deletedLinkAddress; - } - - template - static typename TStorage::LinkAddressType Delete(TStorage& storage, typename TStorage::LinkAddressType linkAddress) - { - auto $continue{storage.Constants.Continue}; - typename TStorage::LinkAddressType deletedLinkAddress; - DIRECT_METHOD_CALL(TStorage, storage, Delete, typename TStorage::LinkType{linkAddress}, [&deletedLinkAddress, $continue] (const typename TStorage::LinkType& before, const typename TStorage::LinkType& after) - { - deletedLinkAddress = before[0]; - return $continue; - }); - return deletedLinkAddress; - } - - template - static typename TStorage::LinkAddressType Count(const TStorage& storage, std::convertible_to auto ...restrictionPack) - // TODO: later add noexcept(expr) - { - typename TStorage::LinkType restriction { static_cast(restrictionPack)... }; - return DIRECT_METHOD_CALL(TStorage, storage, Count, restriction); - } - - 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 - static typename TStorage::LinkAddressType Each(const TStorage& storage, const typename TStorage::ReadHandlerType& handler, std::convertible_to auto... restriction) - // TODO: later create noexcept(expr) - { - typename TStorage::LinkType restrictionContainer { static_cast(restriction)... }; - return DIRECT_METHOD_CALL(TStorage, storage, Each, restrictionContainer, handler); - } + return createdLinkAddress; +} + +template +static typename TStorage::LinkAddressType +Create(TStorage& storage, std::convertible_to auto... substitutionPack) +{ + typename TStorage::LinkType substitution{static_cast(substitutionPack)...}; + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType createdLinkAddress; + DIRECT_METHOD_CALL(TStorage, + storage, + Create, + substitution, + [&createdLinkAddress, $continue](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + createdLinkAddress = after[0]; + return $continue; + }); + return createdLinkAddress; +} + +template +static typename TStorage::LinkAddressType Update(TStorage& storage, + const typename TStorage::LinkType& restriction, + const typename TStorage::LinkType& substitution) +{ + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType updatedLinkAddress; + DIRECT_METHOD_CALL(TStorage, + storage, + Update, + restriction, + substitution, + [&updatedLinkAddress, $continue](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + updatedLinkAddress = after[0]; + return $continue; + }); + return updatedLinkAddress; +} + +template +static typename TStorage::LinkAddressType Delete(TStorage& storage, const typename TStorage::LinkType& restriction) +{ + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType deletedLinkAddress; + DIRECT_METHOD_CALL(TStorage, + storage, + Delete, + restriction, + [&deletedLinkAddress, $continue](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + deletedLinkAddress = before[0]; + return $continue; + }); + return deletedLinkAddress; +} + +template +static typename TStorage::LinkAddressType Delete(TStorage& storage, typename TStorage::LinkAddressType linkAddress) +{ + auto $continue{storage.Constants.Continue}; + typename TStorage::LinkAddressType deletedLinkAddress; + DIRECT_METHOD_CALL(TStorage, + storage, + Delete, + typename TStorage::LinkType{linkAddress}, + [&deletedLinkAddress, $continue](const typename TStorage::LinkType& before, + const typename TStorage::LinkType& after) + { + deletedLinkAddress = before[0]; + return $continue; + }); + return deletedLinkAddress; +} + +template +static typename TStorage::LinkAddressType +Count(const TStorage& storage, std::convertible_to auto... restrictionPack) +// TODO: later add noexcept(expr) +{ + typename TStorage::LinkType restriction{static_cast(restrictionPack)...}; + return DIRECT_METHOD_CALL(TStorage, storage, Count, restriction); +} + +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 - static typename TStorage::LinkType GetLink(const TStorage& storage, typename TStorage::LinkAddressType linkAddress) +template +static typename TStorage::LinkAddressType +Each(const TStorage& storage, + const typename TStorage::ReadHandlerType& handler, + std::convertible_to auto... restriction) +// TODO: later create noexcept(expr) +{ + typename TStorage::LinkType restrictionContainer{static_cast(restriction)...}; + return DIRECT_METHOD_CALL(TStorage, storage, Each, restrictionContainer, handler); +} + +template +static typename TStorage::LinkType GetLink(const TStorage& storage, typename TStorage::LinkAddressType linkAddress) +{ + constexpr auto constants = storage.Constants; + auto $continue = constants.Continue; + auto any = constants.Any; + if (IsExternalReference(linkAddress)) { - constexpr auto constants = storage.Constants; - auto $continue = constants.Continue; - auto any = constants.Any; - if (IsExternalReference(linkAddress)) - { - typename TStorage::LinkType resultLink {linkAddress, linkAddress, linkAddress}; - return resultLink; - } - typename TStorage::LinkType resultLink; - DIRECT_METHOD_CALL(TStorage, storage, Each, typename TStorage::LinkType{linkAddress}, [&resultLink, $continue](const typename TStorage::LinkType& link) - { - resultLink = link; - return $continue; - }); - Ensures(!resultLink.empty()); + typename TStorage::LinkType resultLink{linkAddress, linkAddress, linkAddress}; return resultLink; } + typename TStorage::LinkType resultLink; + DIRECT_METHOD_CALL(TStorage, + storage, + Each, + typename TStorage::LinkType{linkAddress}, + [&resultLink, $continue](const typename TStorage::LinkType& link) + { + resultLink = link; + return $continue; + }); + Ensures(!resultLink.empty()); + return resultLink; +} - template - static bool IsFullPoint(TStorage& storage, typename TStorage::LinkAddressType link) +template static bool IsFullPoint(TStorage& storage, typename TStorage::LinkAddressType link) +{ + if (IsExternalReference(storage.Constants, link)) { - if (IsExternalReference(storage.Constants, link)) - { - return true; - } - Ensures(DIRECT_METHOD_CALL(TStorage, storage, Exists, link)); - return Point::IsFullPoint(DIRECT_METHOD_CALL(TStorage, storage, GetLink, link)); + return true; } + Ensures(DIRECT_METHOD_CALL(TStorage, storage, Exists, link)); + return Point::IsFullPoint(DIRECT_METHOD_CALL(TStorage, storage, GetLink, link)); +} - template - static bool IsPartialPoint(TStorage& storage, typename TStorage::LinkAddressType link) +template static bool IsPartialPoint(TStorage& storage, typename TStorage::LinkAddressType link) +{ + if (IsExternalReference(storage.Constants, link)) { - if (IsExternalReference(storage.Constants, link)) - { - return true; - } - Ensures(DIRECT_METHOD_CALL(TStorage, storage, Exists, link)); - return Point::IsPartialPoint(DIRECT_METHOD_CALL(TStorage, storage, GetLink, link)); + return true; } + Ensures(DIRECT_METHOD_CALL(TStorage, storage, Exists, link)); + return Point::IsPartialPoint( + DIRECT_METHOD_CALL(TStorage, storage, GetLink, link)); } +} // namespace Platform::Data diff --git a/cpp/Platform.Data/ISynchronizedLinks.h b/cpp/Platform.Data/ISynchronizedLinks.h index 7d6b0627..ddead539 100644 --- a/cpp/Platform.Data/ISynchronizedLinks.h +++ b/cpp/Platform.Data/ISynchronizedLinks.h @@ -1,11 +1,14 @@ namespace Platform::Data { - // TODO: rework Platform.Threading - template class ISynchronizedLinks; - template class ISynchronizedLinks : public ISynchronized, ILinks - where TLinks : ILinks - where TConstants : LinksConstants - { - public: - } +// TODO: rework Platform.Threading +template class ISynchronizedLinks; +template +class ISynchronizedLinks : public ISynchronized, + ILinks + where TLinks : ILinks + where TConstants + : LinksConstants +{ +public: } +} // namespace Platform::Data diff --git a/cpp/Platform.Data/LinkAddress.h b/cpp/Platform.Data/LinkAddress.h index 7a4adb70..697d4774 100644 --- a/cpp/Platform.Data/LinkAddress.h +++ b/cpp/Platform.Data/LinkAddress.h @@ -1,77 +1,88 @@ namespace Platform::Data { - template - class LinkAddress - { - public: const TLinkAddress Index; +template class LinkAddress +{ +public: + const TLinkAddress Index; - public: auto operator[](std::integral auto index) const -> const TLinkAddress& +public: + auto operator[](std::integral auto index) const -> const TLinkAddress& + { + if (index == 0) { - if (index == 0) - { - return Index; - } - else - { - throw std::out_of_range{""}; - } + return Index; } - - public: [[nodiscard]] constexpr auto size() const noexcept -> std::size_t + else { - return 1; + throw std::out_of_range{""}; } + } - public: explicit LinkAddress(TLinkAddress index) - : Index(index) - { - } +public: + [[nodiscard]] constexpr auto size() const noexcept -> std::size_t + { + return 1; + } - public: template explicit LinkAddress(const LinkAddress& linkAddress) - : Index(linkAddress.Index) - { - } +public: + explicit LinkAddress(TLinkAddress index) : Index(index) + { + } - public: [[nodiscard]] auto begin() const noexcept -> const TLinkAddress* - { - return std::addressof(Index); - } +public: + template + explicit LinkAddress(const LinkAddress& linkAddress) : Index(linkAddress.Index) + { + } - public: [[nodiscard]] auto end() const noexcept -> const TLinkAddress* - { - // TODO: maybe explicit write "+ 1" instead - return std::addressof(Index) + size(); - } +public: + [[nodiscard]] auto begin() const noexcept -> const TLinkAddress* + { + return std::addressof(Index); + } - public: auto operator==(LinkAddress other) const noexcept - { - return Index == other.Index; - } +public: + [[nodiscard]] auto end() const noexcept -> const TLinkAddress* + { + // TODO: maybe explicit write "+ 1" instead + return std::addressof(Index) + size(); + } - public: explicit operator TLinkAddress() const noexcept - { - return Index; - } +public: + auto operator==(LinkAddress other) const noexcept + { + return Index == other.Index; + } - public: operator std::vector() const - { - return std::vector{Index}; - } +public: + explicit operator TLinkAddress() const noexcept + { + return Index; + } - public: explicit operator std::string() const { return Converters::To(Index); } +public: + operator std::vector() const + { + return std::vector{Index}; + } - public: friend std::ostream& operator<<(std::ostream& stream, LinkAddress self) - { - return stream << static_cast(self); - } - }; +public: + explicit operator std::string() const + { + return Converters::To(Index); + } + +public: + friend std::ostream& operator<<(std::ostream& stream, LinkAddress self) + { + return stream << static_cast(self); + } +}; - template - LinkAddress(TLinkAddress) -> LinkAddress; -} +template LinkAddress(TLinkAddress) -> LinkAddress; +} // namespace Platform::Data -template -struct std::hash> +template struct std::hash> { std::size_t operator()(auto&& self) const { diff --git a/cpp/Platform.Data/LinksConstants.h b/cpp/Platform.Data/LinksConstants.h index e55b4edb..05643947 100644 --- a/cpp/Platform.Data/LinksConstants.h +++ b/cpp/Platform.Data/LinksConstants.h @@ -1,127 +1,131 @@ namespace Platform::Data { - template - struct LinksConstants +template struct LinksConstants +{ + static constexpr int DefaultTargetPart = 2; + +public: + const TLinkAddress IndexPart{}; + +public: + const TLinkAddress SourcePart{}; + +public: + const TLinkAddress TargetPart{}; + +public: + const TLinkAddress Continue{}; + +public: + const TLinkAddress Break{}; + +public: + const TLinkAddress Skip{}; + +public: + const TLinkAddress Null{}; + +public: + const TLinkAddress Any{}; + +public: + const TLinkAddress Itself{}; + +public: + const TLinkAddress Error{}; + +public: + const Ranges::Range InternalReferencesRange{}; + +public: + const Ranges::Range ExternalReferencesRange = std::nullopt; + const bool IsExternalReferencesRangeEnabled; + +public: + constexpr LinksConstants(TLinkAddress targetPart, + const Ranges::Range& possibleInternalReferencesRange, + Ranges::Range possibleExternalReferencesRange) noexcept + : IndexPart(0), SourcePart(1), TargetPart(targetPart), Continue(possibleInternalReferencesRange.Maximum), + Break(possibleInternalReferencesRange.Maximum - 1), Skip(possibleInternalReferencesRange.Maximum - 2), + Null(TLinkAddress{}), Any(possibleInternalReferencesRange.Maximum - 3), + Itself(possibleInternalReferencesRange.Maximum - 4), Error(possibleInternalReferencesRange.Maximum - 5), + InternalReferencesRange( + Ranges::Range{possibleInternalReferencesRange.Minimum, + static_cast(possibleInternalReferencesRange.Maximum - 6)}), + ExternalReferencesRange(possibleExternalReferencesRange), + IsExternalReferencesRangeEnabled(possibleExternalReferencesRange.Minimum != + possibleExternalReferencesRange.Maximum) { - static constexpr int DefaultTargetPart = 2; - public: - const TLinkAddress IndexPart{}; - - public: - const TLinkAddress SourcePart{}; - - public: - const TLinkAddress TargetPart{}; - - public: - const TLinkAddress Continue{}; - - public: - const TLinkAddress Break{}; - - public: - const TLinkAddress Skip{}; - - public: - const TLinkAddress Null{}; - - public: - const TLinkAddress Any{}; - - public: - const TLinkAddress Itself{}; - - public: - const TLinkAddress Error{}; - - public: - const Ranges::Range InternalReferencesRange{}; - - public: - const Ranges::Range ExternalReferencesRange = std::nullopt; - const bool IsExternalReferencesRangeEnabled; - - public: - constexpr LinksConstants(TLinkAddress targetPart, const Ranges::Range& possibleInternalReferencesRange, Ranges::Range possibleExternalReferencesRange) noexcept - : - IndexPart(0), - SourcePart(1), - TargetPart(targetPart), - Continue(possibleInternalReferencesRange.Maximum), - Break(possibleInternalReferencesRange.Maximum - 1), - Skip(possibleInternalReferencesRange.Maximum - 2), - Null(TLinkAddress{}), - Any(possibleInternalReferencesRange.Maximum - 3), - Itself(possibleInternalReferencesRange.Maximum - 4), - Error(possibleInternalReferencesRange.Maximum - 5), - InternalReferencesRange(Ranges::Range{possibleInternalReferencesRange.Minimum, static_cast(possibleInternalReferencesRange.Maximum - 6)}), - ExternalReferencesRange(possibleExternalReferencesRange), - IsExternalReferencesRangeEnabled(possibleExternalReferencesRange.Minimum != possibleExternalReferencesRange.Maximum) - { - } + } - public: - constexpr explicit LinksConstants(TLinkAddress targetPart, bool enableExternalReferencesSupport) noexcept : - LinksConstants(targetPart, GetDefaultInternalReferencesRange(enableExternalReferencesSupport), GetDefaultExternalReferencesRange(enableExternalReferencesSupport)) - { - } +public: + constexpr explicit LinksConstants(TLinkAddress targetPart, bool enableExternalReferencesSupport) noexcept + : LinksConstants(targetPart, + GetDefaultInternalReferencesRange(enableExternalReferencesSupport), + GetDefaultExternalReferencesRange(enableExternalReferencesSupport)) + { + } - public: - constexpr explicit LinksConstants(Ranges::Range possibleInternalReferencesRange, Ranges::Range possibleExternalReferencesRange) noexcept : - LinksConstants(DefaultTargetPart, possibleInternalReferencesRange, possibleExternalReferencesRange) - { - } +public: + constexpr explicit LinksConstants(Ranges::Range possibleInternalReferencesRange, + Ranges::Range possibleExternalReferencesRange) noexcept + : LinksConstants(DefaultTargetPart, possibleInternalReferencesRange, possibleExternalReferencesRange) + { + } - public: - constexpr explicit LinksConstants(bool enableExternalReferencesSupport) noexcept : - LinksConstants(GetDefaultInternalReferencesRange(enableExternalReferencesSupport), GetDefaultExternalReferencesRange(enableExternalReferencesSupport)) - { - } +public: + constexpr explicit LinksConstants(bool enableExternalReferencesSupport) noexcept + : LinksConstants(GetDefaultInternalReferencesRange(enableExternalReferencesSupport), + GetDefaultExternalReferencesRange(enableExternalReferencesSupport)) + { + } - public: - constexpr explicit LinksConstants(TLinkAddress targetPart, Ranges::Range possibleInternalReferencesRange) noexcept : - LinksConstants(targetPart, possibleInternalReferencesRange, std::nullopt) - { - } +public: + constexpr explicit LinksConstants(TLinkAddress targetPart, + Ranges::Range possibleInternalReferencesRange) noexcept + : LinksConstants(targetPart, possibleInternalReferencesRange, std::nullopt) + { + } - public: - constexpr explicit LinksConstants(Ranges::Range possibleInternalReferencesRange) noexcept : - LinksConstants(DefaultTargetPart, possibleInternalReferencesRange, std::nullopt) +public: + constexpr explicit LinksConstants(Ranges::Range possibleInternalReferencesRange) noexcept + : LinksConstants(DefaultTargetPart, possibleInternalReferencesRange, std::nullopt) + { + } + +public: + constexpr explicit LinksConstants() noexcept : LinksConstants(DefaultTargetPart, false) + { + } + +public: + static constexpr Ranges::Range + GetDefaultInternalReferencesRange(bool enableExternalReferencesSupport) noexcept + { + using namespace Ranges; + + if (enableExternalReferencesSupport) { + return Range{1, static_cast(Hybrid::HalfOfNumberValuesRange)}; } - - public: - constexpr explicit LinksConstants() noexcept : - LinksConstants(DefaultTargetPart, false) + else { + return Range{1, std::numeric_limits::max()}; } + } - public: - static constexpr Ranges::Range GetDefaultInternalReferencesRange(bool enableExternalReferencesSupport) noexcept +public: + static constexpr auto + GetDefaultExternalReferencesRange(bool enableExternalReferencesSupport) noexcept -> Ranges::Range + { + if (enableExternalReferencesSupport) { - using namespace Ranges; - - if (enableExternalReferencesSupport) - { - return Range{1, static_cast(Hybrid::HalfOfNumberValuesRange)}; - } - else - { - return Range{1, std::numeric_limits::max()}; - } + return Ranges::Range{Hybrid::ExternalZero, std::numeric_limits::max()}; } - - public: - static constexpr auto GetDefaultExternalReferencesRange(bool enableExternalReferencesSupport) noexcept -> Ranges::Range + else { - if (enableExternalReferencesSupport) - { - return Ranges::Range{Hybrid::ExternalZero, std::numeric_limits::max()}; - } - else - { - return Ranges::Range{0}; - } + return Ranges::Range{0}; } - }; -}// namespace Platform::Data + } +}; +} // namespace Platform::Data diff --git a/cpp/Platform.Data/LinksConstantsExtensions.h b/cpp/Platform.Data/LinksConstantsExtensions.h index 630a17a9..c64f1d9d 100644 --- a/cpp/Platform.Data/LinksConstantsExtensions.h +++ b/cpp/Platform.Data/LinksConstantsExtensions.h @@ -1,21 +1,21 @@ namespace Platform::Data { - template VLinksConstants> - static bool IsInternalReference(TLinkAddress linkAddress) noexcept - { - return VLinksConstants.InternalReferencesRange.Contains(linkAddress); - } +template VLinksConstants> +static bool IsInternalReference(TLinkAddress linkAddress) noexcept +{ + return VLinksConstants.InternalReferencesRange.Contains(linkAddress); +} - template VLinksConstants> - static bool IsReference(TLinkAddress linkAddress) noexcept - { - return IsInternalReference(VLinksConstants, linkAddress) || IsExternalReference(VLinksConstants, linkAddress); - } +template VLinksConstants> +static bool IsReference(TLinkAddress linkAddress) noexcept +{ + return IsInternalReference(VLinksConstants, linkAddress) || IsExternalReference(VLinksConstants, linkAddress); +} - template VLinksConstants> - static bool IsExternalReference(TLinkAddress linkAddress) noexcept - { - auto&& range = VLinksConstants.ExternalReferencesRange; - return range.Contains(linkAddress); - } +template VLinksConstants> +static bool IsExternalReference(TLinkAddress linkAddress) noexcept +{ + auto&& range = VLinksConstants.ExternalReferencesRange; + return range.Contains(linkAddress); } +} // namespace Platform::Data diff --git a/cpp/Platform.Data/LinksOptions.h b/cpp/Platform.Data/LinksOptions.h index c33f8ad9..83ea7b59 100644 --- a/cpp/Platform.Data/LinksOptions.h +++ b/cpp/Platform.Data/LinksOptions.h @@ -1,21 +1,25 @@ namespace Platform::Data { - template VConstants = LinksConstants{true}, typename TLink = std::vector, typename TReadHandler = std::function, typename TWriteHandler = std::function> - struct LinksOptions - { - using LinkAddressType = TLinkAddress; - using LinkType = TLink; - using ReadHandlerType = TReadHandler; - using WriteHandlerType = TWriteHandler; - static constexpr LinksConstants Constants = VConstants; - }; +template VConstants = LinksConstants{true}, + typename TLink = std::vector, + typename TReadHandler = std::function, + typename TWriteHandler = std::function> +struct LinksOptions +{ + using LinkAddressType = TLinkAddress; + using LinkType = TLink; + using ReadHandlerType = TReadHandler; + using WriteHandlerType = TWriteHandler; + static constexpr LinksConstants Constants = VConstants; +}; // template // struct LinksOptions; // -// template VConstants, typename TLink, typename TWriteHandler, typename TReadHandler> -// struct LinksOptions +// template VConstants, typename TLink, typename TWriteHandler, +// typename TReadHandler> struct LinksOptions // { // using LinkAddressType = TLinkAddress; // using LinkType = std::vector; @@ -26,14 +30,16 @@ namespace Platform::Data // // // template VConstants, typename TLink, typename TWriteHandler> -// struct LinksOptions : LinksOptions> +// struct LinksOptions : LinksOptions> // { // // }; // // // template VConstants, typename TLink> -// struct LinksOptions : LinksOptions> +// struct LinksOptions : LinksOptions> // { // // }; @@ -55,5 +61,4 @@ namespace Platform::Data // // }; - -} +} // namespace Platform::Data diff --git a/cpp/Platform.Data/Numbers/Raw/AddressToRawNumberConverter.h b/cpp/Platform.Data/Numbers/Raw/AddressToRawNumberConverter.h index 61f351d5..e30c3298 100644 --- a/cpp/Platform.Data/Numbers/Raw/AddressToRawNumberConverter.h +++ b/cpp/Platform.Data/Numbers/Raw/AddressToRawNumberConverter.h @@ -1,7 +1,11 @@ namespace Platform::Data::Numbers::Raw { - template class AddressToRawNumberConverter +template class AddressToRawNumberConverter +{ +public: + TLink operator()(TLink source) const noexcept { - public: TLink operator()(TLink source) const noexcept { return static_cast(Hybrid(source, true)); } - }; -} + return static_cast(Hybrid(source, true)); + } +}; +} // namespace Platform::Data::Numbers::Raw diff --git a/cpp/Platform.Data/Numbers/Raw/RawNumberToAddressConverter.h b/cpp/Platform.Data/Numbers/Raw/RawNumberToAddressConverter.h index 8a028d05..11b2cf9e 100644 --- a/cpp/Platform.Data/Numbers/Raw/RawNumberToAddressConverter.h +++ b/cpp/Platform.Data/Numbers/Raw/RawNumberToAddressConverter.h @@ -1,8 +1,12 @@ namespace Platform::Data::Numbers::Raw { - template class RawNumberToAddressConverter +template class RawNumberToAddressConverter +{ + // TODO: maybe use C++ functor style? [std::hash and other] +public: + TLink operator()(TLink source) const noexcept { - // TODO: maybe use C++ functor style? [std::hash and other] - public: TLink operator()(TLink source) const noexcept { return Hybrid(source).AbsoluteValue(); } - }; -} + return Hybrid(source).AbsoluteValue(); + } +}; +} // namespace Platform::Data::Numbers::Raw diff --git a/cpp/Platform.Data/Platform.Data.h b/cpp/Platform.Data/Platform.Data.h index b4f3215f..7fc3e8e1 100644 --- a/cpp/Platform.Data/Platform.Data.h +++ b/cpp/Platform.Data/Platform.Data.h @@ -1,20 +1,20 @@ #pragma once +#include #include #include -#include #include "WriteHandlerState.h" #include "Numbers/Raw/AddressToRawNumberConverter.h" #include "Numbers/Raw/RawNumberToAddressConverter.h" -#include "LinkAddress.h" -#include "Point.h" #include "Hybrid.h" +#include "ILinks.h" +#include "LinkAddress.h" #include "LinksConstants.h" -#include "LinksOptions.h" #include "LinksConstantsExtensions.h" -#include "ILinks.h" +#include "LinksOptions.h" +#include "Point.h" #include "ILinksExtensions.h" diff --git a/cpp/Platform.Data/Point.h b/cpp/Platform.Data/Point.h index 85ca9882..84bb8aee 100644 --- a/cpp/Platform.Data/Point.h +++ b/cpp/Platform.Data/Point.h @@ -2,118 +2,135 @@ namespace Platform::Data { - namespace Internal - { - auto gen_always_index(auto index) - { - return [index](auto) { return index; }; - } - - template - using PointBase = decltype(std::views::iota(std::size_t{}, std::size_t{}) | std::views::transform(Internal::gen_always_index(TLinkAddress{}))); - } +namespace Internal +{ +auto gen_always_index(auto index) +{ + return [index](auto) { return index; }; +} - template - class Point : public Internal::PointBase - { - using base = Internal::PointBase; +template +using PointBase = decltype(std::views::iota(std::size_t{}, std::size_t{}) | + std::views::transform(Internal::gen_always_index(TLinkAddress{}))); +} // namespace Internal - // TODO: maybe remove or convert to property - public: const TLinkAddress Index; +template class Point : public Internal::PointBase +{ + using base = Internal::PointBase; - // TODO: maybe remove or convert to property - public: const std::size_t Size; + // TODO: maybe remove or convert to property +public: + const TLinkAddress Index; - public: auto operator[](std::size_t index) const -> TLinkAddress - { - if (index < Size) - { - return Index; - } - else - { - throw std::out_of_range{""}; - } - } + // TODO: maybe remove or convert to property +public: + const std::size_t Size; - 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)) +public: + auto operator[](std::size_t index) const -> TLinkAddress + { + if (index < Size) { + return Index; } - - public: auto operator==(const LinkAddress &other) const noexcept + else { - return Index == other.Index; + throw std::out_of_range{""}; } + } - public: explicit operator TLinkAddress() const noexcept { return Index; } - - public: explicit operator std::string() const { return Converters::To(Index).data(); } - - public: friend std::ostream& operator<<(std::ostream& stream, const Point& self) { return stream << static_cast(self); } - }; - - template - Point(TLinkAddress, Args...) -> Point; +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)) + { + } - static bool IsFullPointUnchecked(Interfaces::CEnumerable auto&& link) - requires std::integral::Item> +public: + auto operator==(const LinkAddress& other) const noexcept { - auto iter = std::ranges::begin(link); - auto end = std::ranges::end(link); - return std::ranges::all_of(iter + 1, end, [&iter](auto&& item) {return item == *iter; }); + return Index == other.Index; } - static bool IsFullPoint(Interfaces::CEnumerable auto&& link) - requires std::integral::Item> +public: + explicit operator TLinkAddress() const noexcept { - using namespace Ranges; - constexpr auto link_range = Range{2, std::numeric_limits::max()}; + return Index; + } - Platform::Ranges::Ensure::Always::ArgumentInRange(std::ranges::size(link), link_range, "link", "Cannot determine link's pointness using only its identifier."); - return IsFullPointUnchecked(link); +public: + explicit operator std::string() const + { + return Converters::To(Index).data(); } - static bool IsFullPoint(std::integral auto... params) +public: + friend std::ostream& operator<<(std::ostream& stream, const Point& self) { - std::common_type_t link[] = { params... }; - return IsFullPoint(link); + return stream << static_cast(self); } +}; + +template Point(TLinkAddress, Args...) -> Point; - static bool IsPartialPointUnchecked(Interfaces::CEnumerable auto&& link) +static bool IsFullPointUnchecked(Interfaces::CEnumerable auto&& link) requires std::integral::Item> - { - auto iter = std::ranges::begin(link); - auto end = std::ranges::end(link); +{ + auto iter = std::ranges::begin(link); + auto end = std::ranges::end(link); + return std::ranges::all_of(iter + 1, end, [&iter](auto&& item) { return item == *iter; }); +} - return std::ranges::any_of(iter + 1, end, [&iter](auto&& item) { return item == *iter; }); - } +static bool IsFullPoint(Interfaces::CEnumerable auto&& link) + requires std::integral::Item> +{ + using namespace Ranges; + constexpr auto link_range = Range{2, std::numeric_limits::max()}; - static bool IsPartialPoint(Interfaces::CEnumerable auto&& link) - { - using namespace Platform::Ranges; + Platform::Ranges::Ensure::Always::ArgumentInRange( + std::ranges::size(link), link_range, "link", "Cannot determine link's pointness using only its identifier."); + return IsFullPointUnchecked(link); +} - // TODO: after my PR - Ensure::Always::ArgumentInRange(std::ranges::size(link) , Range{2, std::numeric_limits::max()}, "link", "Cannot determine link's pointness using only its identifier."); - return IsPartialPointUnchecked(link); - } +static bool IsFullPoint(std::integral auto... params) +{ + std::common_type_t link[] = {params...}; + return IsFullPoint(link); +} - // TODO: we don't have args... to array-like converter - static bool IsPartialPoint(std::integral auto... params) - { - std::common_type_t link[] = { params... }; - static_assert(Interfaces::CEnumerable); - return IsPartialPoint(link); - } +static bool IsPartialPointUnchecked(Interfaces::CEnumerable auto&& link) + requires std::integral::Item> +{ + auto iter = std::ranges::begin(link); + auto end = std::ranges::end(link); + + return std::ranges::any_of(iter + 1, end, [&iter](auto&& item) { return item == *iter; }); } +static bool IsPartialPoint(Interfaces::CEnumerable auto&& link) +{ + using namespace Platform::Ranges; + + // TODO: after my PR + Ensure::Always::ArgumentInRange(std::ranges::size(link), + Range{2, std::numeric_limits::max()}, + "link", + "Cannot determine link's pointness using only its identifier."); + return IsPartialPointUnchecked(link); +} + +// TODO: we don't have args... to array-like converter +static bool IsPartialPoint(std::integral auto... params) +{ + std::common_type_t link[] = {params...}; + static_assert(Interfaces::CEnumerable); + return IsPartialPoint(link); +} +} // namespace Platform::Data -template -struct std::hash> +template struct std::hash> { std::size_t operator()(const Platform::Data::Point& self) const noexcept { return self.Index; } }; - diff --git a/cpp/Platform.Data/Universal/IUniLinks.h b/cpp/Platform.Data/Universal/IUniLinks.h index 16cc1c9f..8f1093ac 100644 --- a/cpp/Platform.Data/Universal/IUniLinks.h +++ b/cpp/Platform.Data/Universal/IUniLinks.h @@ -4,22 +4,29 @@ namespace Platform::Data::Universal { - public partial interface IUniLinks - { - IList>> Trigger(IList &condition, IList &substitution); - } +public +partial interface IUniLinks +{ + IList>> Trigger(IList & condition, IList & substitution); +} - public partial interface IUniLinks - { - TLinkAddress Trigger(IList &patternOrCondition, Func, TLinkAddress> matchHandler, - IList &substitution, Func, IList, TLinkAddress> substitutionHandler); +public +partial interface IUniLinks +{ + TLinkAddress Trigger(IList & patternOrCondition, + Func, TLinkAddress> matchHandler, + IList & substitution, + Func, IList, TLinkAddress> substitutionHandler); - TLinkAddress Trigger(IList &restriction, Func, IList, TLinkAddress> matchedHandler, - IList &substitution, Func, IList, TLinkAddress> substitutedHandler); - } + TLinkAddress Trigger(IList & restriction, + Func, IList, TLinkAddress> matchedHandler, + IList & substitution, + Func, IList, TLinkAddress> substitutedHandler); +} - public partial interface IUniLinks - { - virtual TLinkAddress Count(IList &restriction) = 0; - } +public +partial interface IUniLinks +{ + virtual TLinkAddress Count(IList & restriction) = 0; } +} // namespace Platform::Data::Universal diff --git a/cpp/Platform.Data/Universal/IUniLinksCRUD.h b/cpp/Platform.Data/Universal/IUniLinksCRUD.h index 0faaa9a6..a6a7b4ab 100644 --- a/cpp/Platform.Data/Universal/IUniLinksCRUD.h +++ b/cpp/Platform.Data/Universal/IUniLinksCRUD.h @@ -4,14 +4,14 @@ namespace Platform::Data::Universal { - template class IUniLinksCRUD; - template class IUniLinksCRUD - { - public: - virtual TLinkAddress Read(std::int32_t partType, TLinkAddress link) = 0; - virtual TLinkAddress Read(Func handler, IList &pattern) = 0; - virtual TLinkAddress Create(IList &parts) = 0; - virtual TLinkAddress Update(IList &before, IList &after) = 0; - virtual void Delete(IList &parts) = 0; - }; -} \ No newline at end of file +template class IUniLinksCRUD; +template class IUniLinksCRUD +{ +public: + virtual TLinkAddress Read(std::int32_t partType, TLinkAddress link) = 0; + virtual TLinkAddress Read(Func handler, IList& pattern) = 0; + virtual TLinkAddress Create(IList& parts) = 0; + virtual TLinkAddress Update(IList& before, IList& after) = 0; + virtual void Delete(IList& parts) = 0; +}; +} // namespace Platform::Data::Universal \ No newline at end of file diff --git a/cpp/Platform.Data/Universal/IUniLinksGS.h b/cpp/Platform.Data/Universal/IUniLinksGS.h index 1f32584a..47cfe575 100644 --- a/cpp/Platform.Data/Universal/IUniLinksGS.h +++ b/cpp/Platform.Data/Universal/IUniLinksGS.h @@ -4,12 +4,12 @@ namespace Platform::Data::Universal { - template class IUniLinksGS; - template class IUniLinksGS - { - public: - virtual TLinkAddress Get(std::int32_t partType, TLinkAddress link) = 0; - virtual TLinkAddress Get(Func handler, IList &pattern) = 0; - virtual TLinkAddress Set(IList &before, IList &after) = 0; - }; -} \ No newline at end of file +template class IUniLinksGS; +template class IUniLinksGS +{ +public: + virtual TLinkAddress Get(std::int32_t partType, TLinkAddress link) = 0; + virtual TLinkAddress Get(Func handler, IList& pattern) = 0; + virtual TLinkAddress Set(IList& before, IList& after) = 0; +}; +} // namespace Platform::Data::Universal \ No newline at end of file diff --git a/cpp/Platform.Data/Universal/IUniLinksIO.h b/cpp/Platform.Data/Universal/IUniLinksIO.h index 59ad94b8..70562624 100644 --- a/cpp/Platform.Data/Universal/IUniLinksIO.h +++ b/cpp/Platform.Data/Universal/IUniLinksIO.h @@ -4,12 +4,12 @@ namespace Platform::Data::Universal { - template class IUniLinksIO; - template class IUniLinksIO - { - public: - virtual bool Out(Func, bool> handler, IList &pattern) = 0; +template class IUniLinksIO; +template class IUniLinksIO +{ +public: + virtual bool Out(Func, bool> handler, IList& pattern) = 0; - virtual TLinkAddress In(IList &before, IList &after) = 0; - }; -} \ No newline at end of file + virtual TLinkAddress In(IList& before, IList& after) = 0; +}; +} // namespace Platform::Data::Universal \ No newline at end of file diff --git a/cpp/Platform.Data/Universal/IUniLinksIOWithExtensions.h b/cpp/Platform.Data/Universal/IUniLinksIOWithExtensions.h index 416a1757..0109d26a 100644 --- a/cpp/Platform.Data/Universal/IUniLinksIOWithExtensions.h +++ b/cpp/Platform.Data/Universal/IUniLinksIOWithExtensions.h @@ -2,14 +2,14 @@ namespace Platform::Data::Universal { - template class IUniLinksIOWithExtensions; - template class IUniLinksIOWithExtensions : public IUniLinksIO - { - public: - virtual TLinkAddress OutOne(std::int32_t partType, IList &pattern) = 0; +template class IUniLinksIOWithExtensions; +template class IUniLinksIOWithExtensions : public IUniLinksIO +{ +public: + virtual TLinkAddress OutOne(std::int32_t partType, IList& pattern) = 0; - IList> OutAll(IList &pattern); + IList> OutAll(IList& pattern); - virtual std::uint64_t OutCount(IList &pattern) = 0; - }; -} \ No newline at end of file + virtual std::uint64_t OutCount(IList& pattern) = 0; +}; +} // namespace Platform::Data::Universal \ No newline at end of file diff --git a/cpp/Platform.Data/Universal/IUniLinksRW.h b/cpp/Platform.Data/Universal/IUniLinksRW.h index e39ee41b..8289e649 100644 --- a/cpp/Platform.Data/Universal/IUniLinksRW.h +++ b/cpp/Platform.Data/Universal/IUniLinksRW.h @@ -4,12 +4,12 @@ namespace Platform::Data::Universal { - template class IUniLinksRW; - template class IUniLinksRW - { - public: - virtual TLinkAddress Read(std::int32_t partType, TLinkAddress link) = 0; - virtual bool Read(Func handler, IList &pattern) = 0; - virtual TLinkAddress Write(IList &before, IList &after) = 0; - }; -} \ No newline at end of file +template class IUniLinksRW; +template class IUniLinksRW +{ +public: + virtual TLinkAddress Read(std::int32_t partType, TLinkAddress link) = 0; + virtual bool Read(Func handler, IList& pattern) = 0; + virtual TLinkAddress Write(IList& before, IList& after) = 0; +}; +} // namespace Platform::Data::Universal \ No newline at end of file diff --git a/cpp/Platform.Data/WriteHandlerState.h b/cpp/Platform.Data/WriteHandlerState.h index ab1c8e08..42efe234 100644 --- a/cpp/Platform.Data/WriteHandlerState.h +++ b/cpp/Platform.Data/WriteHandlerState.h @@ -1,36 +1,41 @@ namespace Platform::Data { - using namespace Platform::Interfaces; - template - struct WriteHandlerState +using namespace Platform::Interfaces; +template struct WriteHandlerState +{ + typename TStorage::LinkAddressType Break; + typename TStorage::LinkAddressType Result = 0; + std::function, + std::vector)> + Handler; + + WriteHandlerState(typename TStorage::LinkAddressType $continue, + typename TStorage::LinkAddressType $break, + auto&& handler) + : Result{$continue}, Break{$break}, Handler{handler} { - typename TStorage::LinkAddressType Break; - typename TStorage::LinkAddressType Result = 0; - std::function, std::vector)> Handler; + } - WriteHandlerState(typename TStorage::LinkAddressType $continue, typename TStorage::LinkAddressType $break, auto&& handler) : - Result{$continue}, Break{$break}, Handler{handler} {} + typename TStorage::LinkAddressType Apply(typename TStorage::LinkAddressType result) + { + if (Break == result) + { + Result = Break; + Handler = nullptr; + } + return Result; + } - typename TStorage::LinkAddressType Apply(typename TStorage::LinkAddressType result) + typename TStorage::LinkAddressType Handle(auto&&... args) + { + if (nullptr == Handler) { - if (Break == result) - { - Result = Break; - Handler = nullptr; - } return Result; } - - typename TStorage::LinkAddressType Handle(auto&& ...args) + else { - if(nullptr == Handler) - { - return Result; - } - else - { - return Apply({Handler(std::forward(args)...)}); - } + return Apply({Handler(std::forward(args)...)}); } - }; -} + } +}; +} // namespace Platform::Data diff --git a/format-apply.sh b/format-apply.sh new file mode 100755 index 00000000..66e81a39 --- /dev/null +++ b/format-apply.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Format apply script similar to spotlessApply for Java +# This script formats all C++ files according to .clang-format + +set -e + +echo "Applying C++ code formatting..." + +# Find all C++ files +cpp_files=$(find . -name "*.cpp" -o -name "*.h" -o -name "*.hpp" -o -name "*.cc" -o -name "*.c" | grep -E "^./cpp/") + +if [ -z "$cpp_files" ]; then + echo "No C++ files found to format" + exit 0 +fi + +# Check if clang-format is available +if ! command -v clang-format &> /dev/null; then + echo "Error: clang-format is not installed" + echo "Please install clang-format to use this script" + exit 1 +fi + +# Count total files +total_files=$(echo "$cpp_files" | wc -l) +echo "Found $total_files C++ files to format" + +# Apply formatting +file_count=0 +formatted_files=0 + +for file in $cpp_files; do + file_count=$((file_count + 1)) + echo "Formatting ($file_count/$total_files): $file" + + # Create backup + cp "$file" "$file.backup" + + # Apply formatting + if clang-format -i "$file"; then + # Check if file was actually changed + if ! cmp -s "$file" "$file.backup"; then + formatted_files=$((formatted_files + 1)) + fi + rm "$file.backup" + else + echo "Warning: Failed to format $file" + mv "$file.backup" "$file" + fi +done + +echo "" +echo "✅ Formatting complete!" +echo " Total files processed: $total_files" +echo " Files modified: $formatted_files" + +if [ $formatted_files -gt 0 ]; then + echo "" + echo "Files have been formatted. Please review the changes before committing." +fi \ No newline at end of file diff --git a/format-check.sh b/format-check.sh new file mode 100755 index 00000000..eb4e5b59 --- /dev/null +++ b/format-check.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Format check script similar to spotlessCheck for Java +# This script checks if all C++ files are properly formatted + +set -e + +echo "Checking C++ code formatting..." + +# Find all C++ files +cpp_files=$(find . -name "*.cpp" -o -name "*.h" -o -name "*.hpp" -o -name "*.cc" -o -name "*.c" | grep -E "^./cpp/") + +if [ -z "$cpp_files" ]; then + echo "No C++ files found to check" + exit 0 +fi + +# Check if clang-format is available +if ! command -v clang-format &> /dev/null; then + echo "Error: clang-format is not installed" + echo "Please install clang-format to use this script" + exit 1 +fi + +# Count total files +total_files=$(echo "$cpp_files" | wc -l) +echo "Found $total_files C++ files to check" + +# Check formatting +unformatted_files=() +file_count=0 + +for file in $cpp_files; do + file_count=$((file_count + 1)) + echo "Checking ($file_count/$total_files): $file" + + if ! clang-format --dry-run --Werror "$file" >/dev/null 2>&1; then + unformatted_files+=("$file") + fi +done + +# Report results +if [ ${#unformatted_files[@]} -eq 0 ]; then + echo "✅ All C++ files are properly formatted!" + exit 0 +else + echo "❌ Found ${#unformatted_files[@]} files that need formatting:" + printf ' %s\n' "${unformatted_files[@]}" + echo "" + echo "Run './format-apply.sh' to fix formatting issues" + exit 1 +fi \ No newline at end of file