From b727818f148a50796bf9783a40d4bb21240d3fed Mon Sep 17 00:00:00 2001 From: konard Date: Wed, 10 Sep 2025 18:55:29 +0300 Subject: [PATCH 1/8] Initial commit with task details for issue #12 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/linksplatform/Interfaces/issues/12 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..999ad51e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/linksplatform/Interfaces/issues/12 +Your prepared branch: issue-12-4a822330 +Your prepared working directory: /tmp/gh-issue-solver-1757519725110 + +Proceed. \ No newline at end of file From ce22cf71028f192fbce97539cc8da06f2d0729c5 Mon Sep 17 00:00:00 2001 From: konard Date: Wed, 10 Sep 2025 18:55:45 +0300 Subject: [PATCH 2/8] Remove CLAUDE.md - PR created successfully --- CLAUDE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 999ad51e..00000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/linksplatform/Interfaces/issues/12 -Your prepared branch: issue-12-4a822330 -Your prepared working directory: /tmp/gh-issue-solver-1757519725110 - -Proceed. \ No newline at end of file From 4e3d995b09092d5e5dd9c2d2024de6ecf61c9690 Mon Sep 17 00:00:00 2001 From: konard Date: Wed, 10 Sep 2025 18:59:15 +0300 Subject: [PATCH 3/8] Add internationalized documentation comments to C++ interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added bilingual English/Russian XML documentation comments to all core C++ interface files - Matches documentation style and content from existing C# interfaces - Covers IFactory, IProvider, ISetter, ICounter, ICriterionMatcher, IProperty, and IProperties interfaces - Follows consistent XML documentation format with , , , and tags Fixes #12 πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../ICounter[TResult, TArgument].h | 24 ++++++++++ cpp/Platform.Interfaces/ICounter[TResult].h | 16 +++++++ cpp/Platform.Interfaces/ICriterionMatcher.h | 20 ++++++++ cpp/Platform.Interfaces/IFactory.h | 16 +++++++ cpp/Platform.Interfaces/IProperties.h | 48 +++++++++++++++++++ cpp/Platform.Interfaces/IProperty.h | 12 +++++ .../IProvider[TProvided, TArgument].h | 24 ++++++++++ .../IProvider[TProvided].h | 16 +++++++ .../ISetter[TValue, TArgument].h | 24 ++++++++++ cpp/Platform.Interfaces/ISetter[TValue].h | 16 +++++++ 10 files changed, 216 insertions(+) diff --git a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h index 0009155f..80896390 100644 --- a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h +++ b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h @@ -4,8 +4,32 @@ namespace Platform::Interfaces { template struct ICounter; + /// + /// Defines a counter that requires an argument to perform a count. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ счётчик, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ трСбуСтся Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ для выполнСния подсчёта. + /// + /// + /// The count result type. + /// Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° подсчёта. + /// + /// + /// The argument type. + /// Π’ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// template struct ICounter { + /// + /// Performs a count. + /// ВыполняСт подсчёт. + /// + /// + /// The argument. + /// АргумСнт. + /// + /// + /// The count result. + /// Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ подсчёта. + /// virtual TResult Count(TArgument argument) = 0; virtual ~ICounter() = default; diff --git a/cpp/Platform.Interfaces/ICounter[TResult].h b/cpp/Platform.Interfaces/ICounter[TResult].h index 44db5464..51ce3a0e 100644 --- a/cpp/Platform.Interfaces/ICounter[TResult].h +++ b/cpp/Platform.Interfaces/ICounter[TResult].h @@ -4,8 +4,24 @@ namespace Platform::Interfaces { template struct ICounter; + /// + /// Defines a counter. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ счётчик. + /// + /// + /// The count result type. + /// Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° подсчёта. + /// template struct ICounter { + /// + /// Performs a count. + /// ВыполняСт подсчёт. + /// + /// + /// The count result. + /// Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ подсчёта. + /// virtual TResult Count() = 0; virtual ~ICounter() = default; diff --git a/cpp/Platform.Interfaces/ICriterionMatcher.h b/cpp/Platform.Interfaces/ICriterionMatcher.h index a2fc4784..c1b3eeef 100644 --- a/cpp/Platform.Interfaces/ICriterionMatcher.h +++ b/cpp/Platform.Interfaces/ICriterionMatcher.h @@ -4,8 +4,28 @@ namespace Platform::Interfaces { template struct ICriterionMatcher; + /// + /// Defines a criterion matcher, that contains a specific method for determining whether the argument matches the criterion or not. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ провСряСт соотвСтствиС ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ ΠΈ содСрТит ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ для опрСдСлСния, соотвСтствуСт Π»ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ ΠΈΠ»ΠΈ Π½Π΅Ρ‚. + /// + /// + /// Argument type. + /// Π’ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// template struct ICriterionMatcher { + /// + /// Determines whether the argument matches the criterion. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚, соотвСтствуСт Π»ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ. + /// + /// + /// The argument. + /// АргумСнт. + /// + /// + /// A value that determines whether the argument matches the criterion. + /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠ΅ соотвСтствуСт Π»ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ. + /// virtual bool IsMatched(TArgument argument) = 0; virtual ~ICriterionMatcher() = default; diff --git a/cpp/Platform.Interfaces/IFactory.h b/cpp/Platform.Interfaces/IFactory.h index 5d7c6b38..5f872e73 100644 --- a/cpp/Platform.Interfaces/IFactory.h +++ b/cpp/Platform.Interfaces/IFactory.h @@ -4,8 +4,24 @@ namespace Platform::Interfaces { template struct IFactory; + /// + /// Defines a factory that produces instances of a specific type. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ, которая ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ экзСмпляры ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. + /// + /// + /// Type of produced instances. + /// Π’ΠΈΠΏ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌΡ‹Ρ… экзСмпляров. + /// template struct IFactory { + /// + /// Creates an instance of TProduct type. + /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ экзСмпляр Ρ‚ΠΈΠΏΠ° TProduct. + /// + /// + /// The instance of TProduct type. + /// ЭкзСмпляр Ρ‚ΠΈΠΏΠ° TProduct. + /// virtual TProduct Create() = 0; virtual ~IFactory() = default; diff --git a/cpp/Platform.Interfaces/IProperties.h b/cpp/Platform.Interfaces/IProperties.h index ff0871c5..65c4627f 100644 --- a/cpp/Platform.Interfaces/IProperties.h +++ b/cpp/Platform.Interfaces/IProperties.h @@ -4,10 +4,58 @@ namespace Platform::Interfaces { template struct IProperties; + /// + /// Defines a properties operator that is able to get or set values of properties of a object of a specific type. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ свойств, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ значСния свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. + /// + /// + /// Object type. + /// Π’ΠΈΠΏ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// Property reference type. + /// Π’ΠΈΠΏ ссылки Π½Π° свойство. + /// + /// + /// Property value type. + /// Π’ΠΈΠΏ значСния свойства. + /// template struct IProperties { + /// + /// Gets the value of the property in the specified object. + /// ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ свойства Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅. + /// + /// + /// The object reference. + /// Бсылка Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. + /// + /// + /// The property reference. + /// Бсылка Π½Π° свойство. + /// + /// + /// The value of the property. + /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ свойства. + /// virtual TValue GetValue(TObject object, TProperty property) = 0; + /// + /// Sets the value of a property in the specified object. + /// УстанавливаСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ свойства Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅. + /// + /// + /// The object reference. + /// Бсылка Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. + /// + /// + /// The property reference. + /// Бсылка Π½Π° свойство. + /// + /// + /// The value. + /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. + /// virtual void SetValue(TObject object, TProperty property, TValue value) = 0; virtual ~IProperties() = default; diff --git a/cpp/Platform.Interfaces/IProperty.h b/cpp/Platform.Interfaces/IProperty.h index f36e9e9b..a75db42c 100644 --- a/cpp/Platform.Interfaces/IProperty.h +++ b/cpp/Platform.Interfaces/IProperty.h @@ -7,6 +7,18 @@ namespace Platform::Interfaces { template struct IProperty; + /// + /// Defines a specific property operator that is able to get or set values of that property. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ³ΠΎ свойства, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ значСния. + /// + /// + /// Object type. + /// Π’ΠΈΠΏ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// Property value type. + /// Π’ΠΈΠΏ значСния свойства. + /// template struct IProperty : public ISetter, IProvider { virtual ~IProperty() = default; diff --git a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h index 119cadca..2cab3e17 100644 --- a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h +++ b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h @@ -4,8 +4,32 @@ namespace Platform::Interfaces { template struct IProvider; + /// + /// Defines the provider of objects/values for which an argument must be specified. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ поставщика ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²/Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, для получСния ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚. + /// + /// + /// Type of provided objects/values. + /// Π’ΠΈΠΏ прСдоставляСмых ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²/Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ. + /// + /// + /// Argument type. + /// Π’ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// template struct IProvider { + /// + /// Provides an object(s)/value(s). + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚(Ρ‹)/Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅(я). + /// + /// + /// The argument required to acquire the object(s)/value(s). + /// АргумСнт, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ для получСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°(ΠΎΠ²)/значСния(ΠΈΠΉ). + /// + /// + /// The object(s)/value(s). + /// ΠžΠ±ΡŠΠ΅ΠΊΡ‚(Ρ‹)/Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅(я). + /// virtual TProvided Get(TArgument argument) = 0; virtual ~IProvider() = default; diff --git a/cpp/Platform.Interfaces/IProvider[TProvided].h b/cpp/Platform.Interfaces/IProvider[TProvided].h index 2f035f3d..b1e60685 100644 --- a/cpp/Platform.Interfaces/IProvider[TProvided].h +++ b/cpp/Platform.Interfaces/IProvider[TProvided].h @@ -4,8 +4,24 @@ namespace Platform::Interfaces { template struct IProvider; + /// + /// Defines the provider of objects/values. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ поставщика ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²/Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ. + /// + /// + /// Type of provided object/value. + /// Π’ΠΈΠΏ прСдоставляСмого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°/значСния. + /// template struct IProvider { + /// + /// Provides an object(s)/value(s). + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚(Ρ‹)/Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅(я). + /// + /// + /// The object(s)/value(s). + /// ΠžΠ±ΡŠΠ΅ΠΊΡ‚(Ρ‹)/Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅(я). + /// virtual TProvided Get() = 0; virtual ~IProvider() = default; diff --git a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h index 52ed8b97..27f4cdd0 100644 --- a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h +++ b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h @@ -4,8 +4,32 @@ namespace Platform::Interfaces { template struct ISetter; + /// + /// Defines an setter that requires an argument to set the passed value as a new state. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ установщик, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ для установки ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ значСния Π² качСствС Π½ΠΎΠ²ΠΎΠ³ΠΎ состояния трСбуСтся Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚. + /// + /// + /// Type of set value. + /// Π’ΠΈΠΏ устанавливаСмого значСния. + /// + /// + /// The argument type. + /// Π’ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// template struct ISetter { + /// + /// Sets the value of a specific property in the specified object. + /// УстанавливаСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ³ΠΎ свойства Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅. + /// + /// + /// The argument. + /// АргумСнт. + /// + /// + /// The value. + /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. + /// virtual void Set(TArgument argument, TValue value) = 0; virtual ~ISetter() = default; diff --git a/cpp/Platform.Interfaces/ISetter[TValue].h b/cpp/Platform.Interfaces/ISetter[TValue].h index a893933a..ee84cebf 100644 --- a/cpp/Platform.Interfaces/ISetter[TValue].h +++ b/cpp/Platform.Interfaces/ISetter[TValue].h @@ -4,8 +4,24 @@ namespace Platform::Interfaces { template struct ISetter; + /// + /// Defines an setter that sets the passed value as a new state. + /// ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ установщик, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ устанавливаСт ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² качСствС Π½ΠΎΠ²ΠΎΠ³ΠΎ состояния. + /// + /// + /// Type of set value. + /// Π’ΠΈΠΏ устанавливаСмого значСния. + /// template struct ISetter { + /// + /// Sets the value of a specific property in the specified object. + /// УстанавливаСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ³ΠΎ свойства Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅. + /// + /// + /// The value. + /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. + /// virtual void Set(TValue value) = 0; virtual ~ISetter() = default; From 8588739836b2aa42f79b326cf30b197d54353716 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 26 Sep 2026 02:32:16 +0000 Subject: [PATCH 4/8] Document public C++ API in English and Russian --- cpp/Platform.Interfaces/CArray.h | 20 ++++++ cpp/Platform.Interfaces/CCli.h | 10 ++- cpp/Platform.Interfaces/CCounter.h | 16 +++++ cpp/Platform.Interfaces/CDictionary.h | 64 +++++++++++++++++++ cpp/Platform.Interfaces/CEnumerable.h | 28 ++++++++ cpp/Platform.Interfaces/CFactory.h | 12 ++++ cpp/Platform.Interfaces/CLink.h | 22 ++++++- cpp/Platform.Interfaces/CLinkAddress.h | 8 +++ cpp/Platform.Interfaces/CLinks.h | 10 ++- cpp/Platform.Interfaces/CList.h | 40 ++++++++++++ cpp/Platform.Interfaces/CMatcher.h | 12 ++++ cpp/Platform.Interfaces/CProperties.h | 20 ++++++ cpp/Platform.Interfaces/CProperty.h | 16 +++++ cpp/Platform.Interfaces/CProvider.h | 16 +++++ cpp/Platform.Interfaces/CSet.h | 40 ++++++++++++ cpp/Platform.Interfaces/CSetter.h | 16 +++++ cpp/Platform.Interfaces/Decorated.h | 24 +++++++ cpp/Platform.Interfaces/DecoratedBase.h | 28 ++++++++ cpp/Platform.Interfaces/DecoratorBase.h | 24 +++++++ cpp/Platform.Interfaces/Extended.h | 16 +++++ cpp/Platform.Interfaces/ExtendedBase.h | 12 ++++ cpp/Platform.Interfaces/ExtendedContainer.h | 16 +++++ .../ExtendedContainerBase.h | 16 +++++ cpp/Platform.Interfaces/ExtendedReference.h | 24 +++++++ .../ExtendedReferenceBase.h | 24 +++++++ cpp/Platform.Interfaces/ICli.h | 6 +- .../ICounter[TResult, TArgument].h | 4 ++ cpp/Platform.Interfaces/ICounter[TResult].h | 4 ++ cpp/Platform.Interfaces/IFactory.h | 4 ++ cpp/Platform.Interfaces/IMatcher.h | 4 ++ cpp/Platform.Interfaces/IProperties.h | 4 ++ cpp/Platform.Interfaces/IProperty.h | 4 ++ .../IProvider[TProvided, TArgument].h | 4 ++ .../IProvider[TProvided].h | 4 ++ .../ISetter[TValue, TArgument].h | 4 ++ cpp/Platform.Interfaces/ISetter[TValue].h | 4 ++ cpp/Platform.Interfaces/Macros.h | 24 +++++++ cpp/Platform.Interfaces/Polymorph.h | 16 +++++ 38 files changed, 616 insertions(+), 4 deletions(-) diff --git a/cpp/Platform.Interfaces/CArray.h b/cpp/Platform.Interfaces/CArray.h index fa68e648..a99ff80e 100644 --- a/cpp/Platform.Interfaces/CArray.h +++ b/cpp/Platform.Interfaces/CArray.h @@ -29,9 +29,29 @@ namespace Platform::Interfaces { } } // namespace Internal + /// + /// Requires an enumerable with indexed random access and, optionally, a specified item type. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»ΡΠ΅ΠΌΡƒΡŽ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ доступом ΠΏΠΎ индСксу ΠΈ, ΠΏΡ€ΠΈ нСобходимости, Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ элСмСнта. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// Optional item types. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ элСмСнтов. + /// template concept CArray = CEnumerable && Internal::CArrayHelpFunction(); + /// + /// Exposes the item and iterator types of an array. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ элСмСнтов ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° массива. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct Array : Enumerable {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CCli.h b/cpp/Platform.Interfaces/CCli.h index 2843a8c8..f5c599ab 100644 --- a/cpp/Platform.Interfaces/CCli.h +++ b/cpp/Platform.Interfaces/CCli.h @@ -5,8 +5,16 @@ #include namespace Platform::Interfaces { + /// + /// Requires a command runner that returns an exit code. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template concept CCli = requires(TSelf self, const std::vector& args) { { self.Run(args) } -> std::same_as; }; -} // namespace Platform::Interfaces \ No newline at end of file +} // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CCounter.h b/cpp/Platform.Interfaces/CCounter.h index 587ab248..d6d124ae 100644 --- a/cpp/Platform.Interfaces/CCounter.h +++ b/cpp/Platform.Interfaces/CCounter.h @@ -3,6 +3,22 @@ #include namespace Platform::Interfaces { + /// + /// Requires a counter returning the specified result, with at most one argument. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ счётчик, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// The result type. + /// Π’ΠΈΠΏ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. + /// + /// + /// Optional argument type. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// template concept CCounter = sizeof...(TArgument) <= 1 && requires(TSelf self, TArgument... argument) { { self.Count(argument...) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CDictionary.h b/cpp/Platform.Interfaces/CDictionary.h index 25f8cffa..a72be95a 100644 --- a/cpp/Platform.Interfaces/CDictionary.h +++ b/cpp/Platform.Interfaces/CDictionary.h @@ -108,23 +108,87 @@ namespace Platform::Interfaces { } } // namespace Internal + /// + /// Requires a mutable enumerable dictionary with lookup, insertion and removal operations. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ измСняСмый пСрСчисляСмый ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ с поиском, вставкой ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ΠΌ. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// Optional key and value types. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΊΠ»ΡŽΡ‡Π° ΠΈ значСния. + /// template concept CDictionary = CEnumerable && Internal::CDictionaryHelpFunction(); + /// + /// Requires a read-only enumerable dictionary with lookup operations. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ доступный Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния пСрСчисляСмый ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ с опСрациями поиска. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// Optional key and value types. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΊΠ»ΡŽΡ‡Π° ΠΈ значСния. + /// template concept CReadonlyDictionary = CEnumerable && Internal::CReadonlyDictionaryHelpFunction(); + /// + /// Exposes the item, key and value types of a mutable dictionary. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ элСмСнта, ΠΊΠ»ΡŽΡ‡Π° ΠΈ значСния измСняСмого словаря. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct Dictionary : Enumerable { + /// + /// The enumerable base type. + /// Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ пСрСчисляСмый Ρ‚ΠΈΠΏ. + /// using base = Enumerable; + /// + /// The key type. + /// Π’ΠΈΠΏ ΠΊΠ»ΡŽΡ‡Π°. + /// using Key = decltype(std::get<0>(std::declval())); + /// + /// The value type. + /// Π’ΠΈΠΏ значСния. + /// using Value = decltype(std::get<1>(std::declval())); }; + /// + /// Exposes the item, key and value types of a read-only dictionary. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ элСмСнта, ΠΊΠ»ΡŽΡ‡Π° ΠΈ значСния словаря, доступного Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct ReadonlyDictionary : Enumerable { + /// + /// The enumerable base type. + /// Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ пСрСчисляСмый Ρ‚ΠΈΠΏ. + /// using base = Enumerable; + /// + /// The key type. + /// Π’ΠΈΠΏ ΠΊΠ»ΡŽΡ‡Π°. + /// using Key = decltype(std::get<0>(std::declval())); + /// + /// The value type. + /// Π’ΠΈΠΏ значСния. + /// using Value = decltype(std::get<1>(std::declval())); }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CEnumerable.h b/cpp/Platform.Interfaces/CEnumerable.h index 66659ed0..2095d96e 100644 --- a/cpp/Platform.Interfaces/CEnumerable.h +++ b/cpp/Platform.Interfaces/CEnumerable.h @@ -3,13 +3,41 @@ #include namespace Platform::Interfaces { + /// + /// Requires a type that can be iterated as a range. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Ρ‚ΠΈΠΏ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template concept CEnumerable = std::ranges::range; + /// + /// Exposes the item, reference and iterator types of an enumerable. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ элСмСнта, ссылки ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° пСрСчисляСмого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct Enumerable { + /// + /// The item value type. + /// Π’ΠΈΠΏ значСния элСмСнта. + /// using Item = std::ranges::range_value_t; + /// + /// The item reference type. + /// Π’ΠΈΠΏ ссылки Π½Π° элСмСнт. + /// using ItemReference = std::ranges::range_reference_t; + /// + /// The iterator type. + /// Π’ΠΈΠΏ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°. + /// using Iter = std::ranges::iterator_t; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CFactory.h b/cpp/Platform.Interfaces/CFactory.h index fee54c74..726caf72 100644 --- a/cpp/Platform.Interfaces/CFactory.h +++ b/cpp/Platform.Interfaces/CFactory.h @@ -3,6 +3,18 @@ #include namespace Platform::Interfaces { + /// + /// Requires a factory that creates the specified product type. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Ρ„Π°Π±Ρ€ΠΈΠΊΡƒ, ΡΠΎΠ·Π΄Π°ΡŽΡ‰ΡƒΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// The type of the created product. + /// Π’ΠΈΠΏ создаваСмого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// template concept CFactory = requires(TSelf self) { { self.Create() } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CLink.h b/cpp/Platform.Interfaces/CLink.h index 5f0671cf..9951e3c7 100644 --- a/cpp/Platform.Interfaces/CLink.h +++ b/cpp/Platform.Interfaces/CLink.h @@ -4,6 +4,14 @@ #include namespace Platform::Interfaces { + /// + /// Requires a link with endpoints, a value type and an empty-state query. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ связь с ΠΊΠΎΠ½Ρ†Π°ΠΌΠΈ, Ρ‚ΠΈΠΏΠΎΠΌ значСния ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΎΠΉ пустого состояния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template concept CLink = requires(TSelf self) { { self.empty() } -> std::same_as; @@ -12,8 +20,20 @@ namespace Platform::Interfaces { { self.end } -> std::same_as; }; + /// + /// Exposes the value type of a link. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏ значСния связи. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct Link { + /// + /// The value type of the link. + /// Π’ΠΈΠΏ значСния связи. + /// using value_type = typename TSelf::value_type; }; -} // namespace Platform::Interfaces \ No newline at end of file +} // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CLinkAddress.h b/cpp/Platform.Interfaces/CLinkAddress.h index e9624f11..1b8cdf29 100644 --- a/cpp/Platform.Interfaces/CLinkAddress.h +++ b/cpp/Platform.Interfaces/CLinkAddress.h @@ -4,6 +4,14 @@ #include namespace Platform::Interfaces { + /// + /// Requires an unsigned integral link address. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π±Π΅Π·Π·Π½Π°ΠΊΠΎΠ²Ρ‹ΠΉ цСлочислСнный адрСс связи. + /// + /// + /// The type checked as a link address. + /// Π’ΠΈΠΏ, провСряСмый ΠΊΠ°ΠΊ адрСс связи. + /// template concept CLinkAddress = std::is_integral::value && std::is_unsigned::value; } diff --git a/cpp/Platform.Interfaces/CLinks.h b/cpp/Platform.Interfaces/CLinks.h index 3d76aebf..f55173f5 100644 --- a/cpp/Platform.Interfaces/CLinks.h +++ b/cpp/Platform.Interfaces/CLinks.h @@ -3,6 +3,14 @@ #include namespace Platform::Interfaces { + /// + /// Requires link storage with counting, enumeration, creation, update and deletion operations. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ связСй с подсчётом, ΠΏΠ΅Ρ€Π΅Π±ΠΎΡ€ΠΎΠΌ, созданиСм, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ΠΌ. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template concept CLinks = requires { typename TSelf::OptionsType; @@ -18,4 +26,4 @@ namespace Platform::Interfaces { { self.Update(restriction, substitution, writeHandler) } -> std::same_as; { self.Delete(restriction, writeHandler) } -> std::same_as; }; -} // namespace Platform::Interfaces \ No newline at end of file +} // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CList.h b/cpp/Platform.Interfaces/CList.h index b1dfb6c2..6e38f6cf 100644 --- a/cpp/Platform.Interfaces/CList.h +++ b/cpp/Platform.Interfaces/CList.h @@ -68,15 +68,55 @@ namespace Platform::Interfaces { } } // namespace Internal + /// + /// Requires an indexed mutable list with insertion and removal operations. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ индСксируСмый измСняСмый список с опСрациями вставки ΠΈ удалСния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// Optional item types. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ элСмСнтов. + /// template concept CList = CArray && Internal::CListHelpFunction(); + /// + /// Requires an indexed read-only list with size and empty-state queries. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ индСксируСмый список Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния с запросами Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΈ пустого состояния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// Optional item types. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ элСмСнтов. + /// template concept CReadonlyList = CArray && Internal::CReadonlyListHelpFunction(); + /// + /// Exposes the item and iterator types of a mutable list. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ элСмСнта ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° измСняСмого списка. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct List : Enumerable {}; + /// + /// Exposes the item and iterator types of a read-only list. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ элСмСнта ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° списка Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct ReadonlyList : Enumerable {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CMatcher.h b/cpp/Platform.Interfaces/CMatcher.h index 66f8b229..aff37876 100644 --- a/cpp/Platform.Interfaces/CMatcher.h +++ b/cpp/Platform.Interfaces/CMatcher.h @@ -3,6 +3,18 @@ #include namespace Platform::Interfaces { + /// + /// Requires a matcher that reports whether a candidate satisfies its rule. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΡΠΎΠΎΠ±Ρ‰Π°ΡŽΡ‰ΠΈΠΉ, соотвСтствуСт Π»ΠΈ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»Ρƒ сопоставлСния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// The type of the candidate to match. + /// Π’ΠΈΠΏ провСряСмого ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚Π°. + /// template concept CMatcher = requires(TSelf self, TCandidate candidate) { { self.IsMatched(candidate) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CProperties.h b/cpp/Platform.Interfaces/CProperties.h index 15fb8250..fd94c3be 100644 --- a/cpp/Platform.Interfaces/CProperties.h +++ b/cpp/Platform.Interfaces/CProperties.h @@ -3,6 +3,26 @@ #include namespace Platform::Interfaces { + /// + /// Requires an operator that gets and sets a named property of an object. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€, ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰ΠΈΠΉ ΠΈ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ свойство ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// The object type. + /// Π’ΠΈΠΏ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The property reference type. + /// Π’ΠΈΠΏ ссылки Π½Π° свойство. + /// + /// + /// The value type. + /// Π’ΠΈΠΏ значСния. + /// template concept CProperties = requires(TSelf self, TObject& object, TProperty property, TValue value) { { self.GetValue(object, property) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CProperty.h b/cpp/Platform.Interfaces/CProperty.h index 532058e1..a13c17a0 100644 --- a/cpp/Platform.Interfaces/CProperty.h +++ b/cpp/Platform.Interfaces/CProperty.h @@ -4,6 +4,22 @@ #include "CSetter.h" namespace Platform::Interfaces { + /// + /// Requires an operator that gets and sets one property of an object. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€, ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰ΠΈΠΉ ΠΈ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ ΠΎΠ΄Π½ΠΎ свойство ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// The object type. + /// Π’ΠΈΠΏ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The value type. + /// Π’ΠΈΠΏ значСния. + /// template concept CProperty = CSetter && CProvider; } diff --git a/cpp/Platform.Interfaces/CProvider.h b/cpp/Platform.Interfaces/CProvider.h index a68711f3..678dfcf9 100644 --- a/cpp/Platform.Interfaces/CProvider.h +++ b/cpp/Platform.Interfaces/CProvider.h @@ -3,6 +3,22 @@ #include namespace Platform::Interfaces { + /// + /// Requires a provider of the specified type with at most one argument. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ поставщика Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅Π³ΠΎ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// The provided type. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅ΠΌΡ‹ΠΉ Ρ‚ΠΈΠΏ. + /// + /// + /// Optional argument type. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// template concept CProvider = sizeof...(TArgument) <= 1 && requires(TSelf self, TArgument... argument) { { self.Get(argument...) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/CSet.h b/cpp/Platform.Interfaces/CSet.h index b61e4365..d1f2bcea 100644 --- a/cpp/Platform.Interfaces/CSet.h +++ b/cpp/Platform.Interfaces/CSet.h @@ -73,15 +73,55 @@ namespace Platform::Interfaces { } // namespace Internal + /// + /// Requires a mutable enumerable set with lookup, insertion and removal operations. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ измСняСмоС пСрСчисляСмоС мноТСство с поиском, вставкой ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ΠΌ. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// Optional item types. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ элСмСнтов. + /// template concept CSet = CEnumerable && Internal::CSetHelpFunction(); + /// + /// Requires a read-only enumerable set with lookup operations. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ доступноС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния пСрСчисляСмоС мноТСство с поиском. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// Optional item types. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ элСмСнтов. + /// template concept CReadonlySet = CEnumerable && Internal::CReadonlySetHelpFunction(); + /// + /// Exposes the item and iterator types of a mutable set. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ элСмСнта ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° измСняСмого мноТСства. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct Set : Enumerable {}; + /// + /// Exposes the item and iterator types of a read-only set. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ элСмСнта ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° мноТСства Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// template struct ReadonlySet : Enumerable {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/CSetter.h b/cpp/Platform.Interfaces/CSetter.h index 72125d16..2b3c2f4d 100644 --- a/cpp/Platform.Interfaces/CSetter.h +++ b/cpp/Platform.Interfaces/CSetter.h @@ -3,6 +3,22 @@ #include namespace Platform::Interfaces { + /// + /// Requires a setter that accepts a value and at most one additional argument. + /// Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ установщик, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// The value type. + /// Π’ΠΈΠΏ значСния. + /// + /// + /// Optional argument type. + /// ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. + /// template concept CSetter = sizeof...(TArgument) <= 1 && requires(TSelf self, TArgument... argument, TValue value) { { self.Set(argument..., value) } -> std::same_as; diff --git a/cpp/Platform.Interfaces/Decorated.h b/cpp/Platform.Interfaces/Decorated.h index 773448fc..a053042c 100644 --- a/cpp/Platform.Interfaces/Decorated.h +++ b/cpp/Platform.Interfaces/Decorated.h @@ -3,10 +3,34 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Composes one or more decorators around an object. + /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ нСсколько Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ² Π²ΠΎΠΊΡ€ΡƒΠ³ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The decorated object type. + /// Π’ΠΈΠΏ Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The first decorator template. + /// Π¨Π°Π±Π»ΠΎΠ½ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π°. + /// + /// + /// The remaining decorator templates. + /// Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ². + /// template typename TFirstDecorator, template typename... TDecorators> struct Decorated : public DecoratedBase, TDecorated, TFirstDecorator, TDecorators...> { + /// + /// The composed decorator base type. + /// Π’ΠΈΠΏ Π±Π°Π·ΠΎΠ²ΠΎΠΉ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ². + /// using base = DecoratedBase, TDecorated, TFirstDecorator, TDecorators...>; + /// + /// Forwards constructor arguments to the decorator chain. + /// ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‘Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ конструктора Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ². + /// USE_ALL_BASE_CONSTRUCTORS(Decorated, base) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/DecoratedBase.h b/cpp/Platform.Interfaces/DecoratedBase.h index e274a854..a55537be 100644 --- a/cpp/Platform.Interfaces/DecoratedBase.h +++ b/cpp/Platform.Interfaces/DecoratedBase.h @@ -3,10 +3,38 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Builds the decorator chain for a facade and its decorated object. + /// Π‘ΠΎΠ·Π΄Π°Ρ‘Ρ‚ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ² для фасада ΠΈ Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The facade type. + /// Π’ΠΈΠΏ фасада. + /// + /// + /// The decorated object type. + /// Π’ΠΈΠΏ Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The first decorator template. + /// Π¨Π°Π±Π»ΠΎΠ½ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π°. + /// + /// + /// The remaining decorator templates. + /// Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ². + /// template typename TFirstDecorator, template typename... TDecorators> struct DecoratedBase : public DECORATED_BASE_TYPE(DecoratedBase, TFacade, TDecorated, TFirstDecorator, TDecorators) { + /// + /// The base type of the decorator chain. + /// Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ Ρ‚ΠΈΠΏ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ². + /// using base = DECORATED_BASE_TYPE(DecoratedBase, TFacade, TDecorated, TFirstDecorator, TDecorators); + /// + /// Forwards constructor arguments to the next decorator. + /// ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‘Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ конструктора ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρƒ. + /// USE_ALL_BASE_CONSTRUCTORS(DecoratedBase, base) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/DecoratorBase.h b/cpp/Platform.Interfaces/DecoratorBase.h index 98488e78..bc9e7488 100644 --- a/cpp/Platform.Interfaces/DecoratorBase.h +++ b/cpp/Platform.Interfaces/DecoratorBase.h @@ -3,11 +3,35 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Provides typed access to a decorated object and its facade. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ доступ ΠΊ Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ ΠΈ Π΅Π³ΠΎ фасаду. + /// + /// + /// The facade type. + /// Π’ΠΈΠΏ фасада. + /// + /// + /// The decorated object type. + /// Π’ΠΈΠΏ Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// template struct DecoratorBase : public TDecorated { + /// + /// Forwards constructor arguments to the decorated type. + /// ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‘Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ конструктора Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ. + /// USE_ALL_BASE_CONSTRUCTORS(DecoratorBase, TDecorated) + /// + /// Accesses the decorated object with the reference category of this object. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ доступ ΠΊ Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ΅ΠΉ ссылки. + /// THIS_REFERENCE_WRAPPER_METHODS(decorated, TDecorated) + /// + /// Accesses the facade with the reference category of this object. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ доступ ΠΊ фасаду с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ΅ΠΉ ссылки. + /// THIS_REFERENCE_WRAPPER_METHODS(facade, TFacade) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/Extended.h b/cpp/Platform.Interfaces/Extended.h index da763ee2..14b34676 100644 --- a/cpp/Platform.Interfaces/Extended.h +++ b/cpp/Platform.Interfaces/Extended.h @@ -4,6 +4,22 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Composes one or more extenders around an object. + /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ ΠΎΠ΄Π½ΠΎ ΠΈΠ»ΠΈ нСсколько Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ Π²ΠΎΠΊΡ€ΡƒΠ³ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The extendable object type. + /// Π’ΠΈΠΏ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The first extender template. + /// Π¨Π°Π±Π»ΠΎΠ½ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ. + /// + /// + /// The remaining extender templates. + /// Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ. + /// template typename TFirstExtender, template typename... TExtenders> class Extended : public EXTENDED_BASE_TYPE(Extended, ExtendedBase, TExtendable, TFirstExtender, TExtenders) {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedBase.h b/cpp/Platform.Interfaces/ExtendedBase.h index 1a5c0b5d..d0db2e1b 100644 --- a/cpp/Platform.Interfaces/ExtendedBase.h +++ b/cpp/Platform.Interfaces/ExtendedBase.h @@ -3,8 +3,20 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Provides typed access to the object being extended. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ доступ ΠΊ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ. + /// + /// + /// The extendable object type. + /// Π’ΠΈΠΏ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// template struct ExtendedBase : public TExtendable { + /// + /// Accesses the extended object with the reference category of this object. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ доступ ΠΊ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ΅ΠΉ ссылки. + /// THIS_REFERENCE_WRAPPER_METHODS(extended, TExtendable) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedContainer.h b/cpp/Platform.Interfaces/ExtendedContainer.h index 707f8ada..14438d68 100644 --- a/cpp/Platform.Interfaces/ExtendedContainer.h +++ b/cpp/Platform.Interfaces/ExtendedContainer.h @@ -4,6 +4,22 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Composes extenders around an object stored by value. + /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Π²ΠΎΠΊΡ€ΡƒΠ³ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Ρ…Ρ€Π°Π½ΠΈΠΌΠΎΠ³ΠΎ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. + /// + /// + /// The extendable object type. + /// Π’ΠΈΠΏ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The first extender template. + /// Π¨Π°Π±Π»ΠΎΠ½ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ. + /// + /// + /// The remaining extender templates. + /// Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ. + /// template typename TFirstExtender, template typename... TExtenders> class ExtendedContainer : public EXTENDED_BASE_TYPE(ExtendedContainer, ExtendedContainerBase, TExtendable, TFirstExtender, TExtenders) {}; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedContainerBase.h b/cpp/Platform.Interfaces/ExtendedContainerBase.h index 87f1eb08..33956378 100644 --- a/cpp/Platform.Interfaces/ExtendedContainerBase.h +++ b/cpp/Platform.Interfaces/ExtendedContainerBase.h @@ -3,12 +3,28 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Stores an extendable object by value and exposes it to derived types. + /// Π₯Ρ€Π°Π½ΠΈΡ‚ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΈ прСдоставляСт Π΅Π³ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠ°ΠΌ. + /// + /// + /// The extendable object type. + /// Π’ΠΈΠΏ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// template class ExtendedContainerBase { public: + /// + /// Accesses the stored object with the reference category of this object. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ доступ ΠΊ Ρ…Ρ€Π°Π½ΠΈΠΌΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ΅ΠΉ ссылки. + /// VARIABLE_WRAPPER_METHODS(extended, extendable) protected: + /// + /// The stored extendable object. + /// Π₯Ρ€Π°Π½ΠΈΠΌΡ‹ΠΉ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. + /// TExtendable extendable; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedReference.h b/cpp/Platform.Interfaces/ExtendedReference.h index 9313f67b..c2cdbb3c 100644 --- a/cpp/Platform.Interfaces/ExtendedReference.h +++ b/cpp/Platform.Interfaces/ExtendedReference.h @@ -4,11 +4,35 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Composes extenders around an object stored by reference. + /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Π²ΠΎΠΊΡ€ΡƒΠ³ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Ρ…Ρ€Π°Π½ΠΈΠΌΠΎΠ³ΠΎ ΠΏΠΎ ссылкС. + /// + /// + /// The extendable object type. + /// Π’ΠΈΠΏ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// + /// + /// The first extender template. + /// Π¨Π°Π±Π»ΠΎΠ½ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ. + /// + /// + /// The remaining extender templates. + /// Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ. + /// template typename TFirstExtender, template typename... TExtenders> class ExtendedReference : public EXTENDED_BASE_TYPE(ExtendedReference, ExtendedReferenceBase, TExtendable, TFirstExtender, TExtenders) { + /// + /// The composed extender base type. + /// Π’ΠΈΠΏ Π±Π°Π·ΠΎΠ²ΠΎΠΉ Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΈ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ. + /// using base = EXTENDED_BASE_TYPE(ExtendedReference, ExtendedReferenceBase, TExtendable, TFirstExtender, TExtenders); public: + /// + /// Forwards constructor arguments to the extender chain. + /// ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‘Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ конструктора Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ. + /// USE_ALL_BASE_CONSTRUCTORS(ExtendedReference, base) }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ExtendedReferenceBase.h b/cpp/Platform.Interfaces/ExtendedReferenceBase.h index ecd077f3..b4864d39 100644 --- a/cpp/Platform.Interfaces/ExtendedReferenceBase.h +++ b/cpp/Platform.Interfaces/ExtendedReferenceBase.h @@ -3,14 +3,38 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Stores an extendable object by reference and exposes it to derived types. + /// Π₯Ρ€Π°Π½ΠΈΡ‚ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎ ссылкС ΠΈ прСдоставляСт Π΅Π³ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠ°ΠΌ. + /// + /// + /// The extendable object type. + /// Π’ΠΈΠΏ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. + /// template class ExtendedReferenceBase { public: + /// + /// Stores a reference to an extendable object. + /// БохраняСт ссылку Π½Π° Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. + /// + /// + /// The object to extend. + /// Π Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. + /// ExtendedReferenceBase(TExtendable& reference) : extendable(reference) {} + /// + /// Accesses the referenced object with the reference category of this object. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ доступ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ ΠΏΠΎ ссылкС с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ΅ΠΉ ссылки. + /// VARIABLE_WRAPPER_METHODS(extended, extendable) protected: + /// + /// The referenced extendable object. + /// Π Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎ ссылкС. + /// TExtendable& extendable; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ICli.h b/cpp/Platform.Interfaces/ICli.h index 86edc188..b7356b9e 100644 --- a/cpp/Platform.Interfaces/ICli.h +++ b/cpp/Platform.Interfaces/ICli.h @@ -23,6 +23,10 @@ namespace Platform::Interfaces { /// virtual int Run(const std::vector& args) = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~ICli() = default; }; -} // namespace Platform::Interfaces \ No newline at end of file +} // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h index 80896390..4c04d097 100644 --- a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h +++ b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h @@ -32,6 +32,10 @@ namespace Platform::Interfaces { /// virtual TResult Count(TArgument argument) = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~ICounter() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ICounter[TResult].h b/cpp/Platform.Interfaces/ICounter[TResult].h index 51ce3a0e..f0bd70e4 100644 --- a/cpp/Platform.Interfaces/ICounter[TResult].h +++ b/cpp/Platform.Interfaces/ICounter[TResult].h @@ -24,6 +24,10 @@ namespace Platform::Interfaces { /// virtual TResult Count() = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~ICounter() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IFactory.h b/cpp/Platform.Interfaces/IFactory.h index 5f872e73..46a78118 100644 --- a/cpp/Platform.Interfaces/IFactory.h +++ b/cpp/Platform.Interfaces/IFactory.h @@ -24,6 +24,10 @@ namespace Platform::Interfaces { /// virtual TProduct Create() = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~IFactory() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IMatcher.h b/cpp/Platform.Interfaces/IMatcher.h index 80d93687..9bc93c94 100644 --- a/cpp/Platform.Interfaces/IMatcher.h +++ b/cpp/Platform.Interfaces/IMatcher.h @@ -28,6 +28,10 @@ namespace Platform::Interfaces { /// virtual bool IsMatched(TCandidate candidate) = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~IMatcher() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IProperties.h b/cpp/Platform.Interfaces/IProperties.h index 65c4627f..b0d31482 100644 --- a/cpp/Platform.Interfaces/IProperties.h +++ b/cpp/Platform.Interfaces/IProperties.h @@ -58,6 +58,10 @@ namespace Platform::Interfaces { /// virtual void SetValue(TObject object, TProperty property, TValue value) = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~IProperties() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IProperty.h b/cpp/Platform.Interfaces/IProperty.h index a75db42c..fdd012f2 100644 --- a/cpp/Platform.Interfaces/IProperty.h +++ b/cpp/Platform.Interfaces/IProperty.h @@ -21,6 +21,10 @@ namespace Platform::Interfaces { /// template struct IProperty : public ISetter, IProvider { + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~IProperty() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h index 2cab3e17..356f0a36 100644 --- a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h +++ b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h @@ -32,6 +32,10 @@ namespace Platform::Interfaces { /// virtual TProvided Get(TArgument argument) = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~IProvider() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/IProvider[TProvided].h b/cpp/Platform.Interfaces/IProvider[TProvided].h index b1e60685..7e9b7069 100644 --- a/cpp/Platform.Interfaces/IProvider[TProvided].h +++ b/cpp/Platform.Interfaces/IProvider[TProvided].h @@ -24,6 +24,10 @@ namespace Platform::Interfaces { /// virtual TProvided Get() = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~IProvider() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h index 27f4cdd0..5c7d1f24 100644 --- a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h +++ b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h @@ -32,6 +32,10 @@ namespace Platform::Interfaces { /// virtual void Set(TArgument argument, TValue value) = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~ISetter() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/ISetter[TValue].h b/cpp/Platform.Interfaces/ISetter[TValue].h index ee84cebf..63d1e663 100644 --- a/cpp/Platform.Interfaces/ISetter[TValue].h +++ b/cpp/Platform.Interfaces/ISetter[TValue].h @@ -24,6 +24,10 @@ namespace Platform::Interfaces { /// virtual void Set(TValue value) = 0; + /// + /// Destroys the interface instance. + /// Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅Ρ‚ экзСмпляр интСрфСйса. + /// virtual ~ISetter() = default; }; } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/Macros.h b/cpp/Platform.Interfaces/Macros.h index 061b5e0b..5f3bc6ce 100644 --- a/cpp/Platform.Interfaces/Macros.h +++ b/cpp/Platform.Interfaces/Macros.h @@ -5,26 +5,50 @@ #include namespace Platform::Interfaces { +/// +/// Generates four reference-qualified accessors that cast this object to the wrapped type. +/// Π‘ΠΎΠ·Π΄Π°Ρ‘Ρ‚ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° доступа с ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°ΠΌΠΈ ссылки, приводящиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊ ΠΎΠ±Ρ‘Ρ€Π½ΡƒΡ‚ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ. +/// #define THIS_REFERENCE_WRAPPER_METHODS(MethodName, TWrapped) \ constexpr auto&& MethodName()& { return static_cast(*this); } \ constexpr auto&& MethodName()&& { return static_cast(*this); } \ constexpr auto&& MethodName() const& { return static_cast(*this); } \ constexpr auto&& MethodName() const&& { return static_cast(*this); } +/// +/// Generates four reference-qualified accessors for a member variable. +/// Π‘ΠΎΠ·Π΄Π°Ρ‘Ρ‚ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° доступа с ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°ΠΌΠΈ ссылки для поля. +/// #define VARIABLE_WRAPPER_METHODS(MethodName, VariableName) \ constexpr auto&& MethodName()& { return VariableName; } \ constexpr auto&& MethodName()&& { return VariableName; } \ constexpr auto&& MethodName() const& { return VariableName; } \ constexpr auto&& MethodName() const&& { return VariableName; } +/// +/// Selects the next type in an extender chain. +/// Π’Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ. +/// #define EXTENDED_BASE_TYPE(TExtended, TExtendedBase, TExtendable, TFirstExtender, TExtenders) TFirstExtender= 2, TExtended, std::tuple_element_t<0, std::tuple>...>>>> +/// +/// Selects the next type in a decorator chain. +/// Π’Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ΅ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ². +/// #define DECORATED_BASE_TYPE(TDecoratedBase, TFacade, TDecorated, TFirstDecorator, TDecorators) TFirstDecorator= 2, TDecoratedBase, std::tuple_element_t<0, std::tuple...>>>> +/// +/// Generates a forwarding constructor for the specified base type. +/// Π‘ΠΎΠ·Π΄Π°Ρ‘Ρ‚ конструктор с ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ Π±Π°Π·ΠΎΠ²ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ. +/// #define USE_ALL_BASE_CONSTRUCTORS(TSelf, TBase) \ template \ TSelf(TParams&&... params) : TBase(std::forward(params)...) {} +/// +/// Calls a method directly for a concrete type or virtually for an abstract type. +/// Π’Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΈΠ»ΠΈ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎ для абстрактного Ρ‚ΠΈΠΏΠ°. +/// #define DIRECT_METHOD_CALL(TClass, Object, MethodName, ...) (std::is_abstract::value ? Object.MethodName(__VA_ARGS__) : Object.TClass::MethodName(__VA_ARGS__)) } // namespace Platform::Interfaces diff --git a/cpp/Platform.Interfaces/Polymorph.h b/cpp/Platform.Interfaces/Polymorph.h index e182ffe6..00340c33 100644 --- a/cpp/Platform.Interfaces/Polymorph.h +++ b/cpp/Platform.Interfaces/Polymorph.h @@ -3,9 +3,25 @@ #include "Macros.h" namespace Platform::Interfaces { + /// + /// Combines base types and exposes the derived object to them. + /// ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΈ прСдоставляСт ΠΈΠΌ доступ ΠΊ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ. + /// + /// + /// The type checked by this concept or described by this helper. + /// Π’ΠΈΠΏ, провСряСмый этим ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠΌ ΠΈΠ»ΠΈ описываСмый этим Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠΎΠΌ. + /// + /// + /// The base types. + /// Π‘Π°Π·ΠΎΠ²Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹. + /// template class Polymorph : public TBase... { protected: + /// + /// Accesses the derived object with the reference category of this object. + /// ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΠ΅Ρ‚ доступ ΠΊ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ΅ΠΉ ссылки. + /// THIS_REFERENCE_WRAPPER_METHODS(object, TSelf) }; } // namespace Platform::Interfaces From abd5fed7e1b0004056c66fdc8af03115f0447a4d Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 26 Sep 2026 02:32:24 +0000 Subject: [PATCH 5/8] Generate and validate complete C++ API documentation in CI --- .github/scripts/check-cpp-docs.py | 98 +++++++++++++++++++ .github/scripts/check-cpp-docs.test.py | 50 ++++++++++ .github/workflows/cpp-docs.yml | 50 ++++++++++ .gitignore | 3 + README.md | 2 + cpp/Doxyfile | 27 +++++ ...Platform.Interfaces.TemplateLibrary.nuspec | 4 +- 7 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 .github/scripts/check-cpp-docs.py create mode 100644 .github/scripts/check-cpp-docs.test.py create mode 100644 .github/workflows/cpp-docs.yml create mode 100644 cpp/Doxyfile diff --git a/.github/scripts/check-cpp-docs.py b/.github/scripts/check-cpp-docs.py new file mode 100644 index 00000000..9e9a08c7 --- /dev/null +++ b/.github/scripts/check-cpp-docs.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +"""Require bilingual documentation on public C++ declarations.""" + +from pathlib import Path +import re +import sys + + +def declaration_kind(line: str) -> str | None: + stripped = line.strip() + if re.match(r"(?:concept|struct|class)\s+\w+", stripped) and ("{" in stripped or "=" in stripped): + return "type" + if re.match(r"using\s+\w+\s*=", stripped): + return "alias" + if stripped.startswith("virtual "): + return "method" + if stripped.startswith("#define "): + return "macro" + if re.match(r"(?:THIS_REFERENCE_WRAPPER_METHODS|VARIABLE_WRAPPER_METHODS|USE_ALL_BASE_CONSTRUCTORS)\(", stripped): + return "generated members" + if re.match(r"ExtendedReferenceBase\(", stripped): + return "constructor" + if re.match(r"TExtendable&?\s+extendable;", stripped): + return "field" + return None + + +def documentation_before(lines: list[str], index: int) -> tuple[str, str]: + previous = index - 1 + template = "" + if previous >= 0 and lines[previous].strip().startswith("template <"): + template = lines[previous].strip() + previous -= 1 + comment = [] + while previous >= 0 and lines[previous].lstrip().startswith("///"): + comment.append(lines[previous].strip()) + previous -= 1 + return "\n".join(reversed(comment)), template + + +def validate_header(path: Path) -> list[str]: + lines = path.read_text(encoding="utf-8-sig").splitlines() + errors = [] + inside_internal = False + for index, line in enumerate(lines): + if "namespace Internal {" in line: + inside_internal = True + if "} // namespace Internal" in line: + inside_internal = False + continue + if inside_internal: + continue + kind = declaration_kind(line) + if kind is None: + continue + comment, template = documentation_before(lines, index) + label = f"{path}:{index + 1}: {kind}" + if "" not in comment or "" not in comment: + errors.append(f"{label} lacks a documentation summary") + continue + paragraphs = re.findall(r"(.*?)", comment) + if not any(re.search(r"[A-Za-z]", paragraph) for paragraph in paragraphs) or not any( + re.search(r"[А-Π―Π°-яЁё]", paragraph) for paragraph in paragraphs + ): + errors.append(f"{label} lacks English and Russian paragraphs") + if kind == "type": + parameters = dict.fromkeys(re.findall(r"\bT(?:[A-Z]\w*)?\b", template)) + for parameter in parameters: + if f'' not in comment: + errors.append(f"{label} lacks documentation for {parameter}") + if kind in {"method", "constructor"}: + signature = line.strip() + arguments = re.search(r"\((.*?)\)", signature) + if arguments: + for argument in arguments.group(1).split(","): + argument = argument.strip() + if not argument: + continue + name = re.search(r"(\w+)$", argument) + if name and f'' not in comment: + errors.append(f"{label} lacks documentation for argument {name.group(1)}") + if kind == "method" and not ("virtual void " in signature or "virtual ~" in signature) and "" not in comment: + errors.append(f"{label} lacks return documentation") + return errors + + +def main() -> int: + root = Path(__file__).resolve().parents[2] / "cpp" / "Platform.Interfaces" + errors = [error for path in sorted(root.glob("*.h")) for error in validate_header(path)] + if errors: + print("\n".join(errors), file=sys.stderr) + return 1 + print(f"Bilingual documentation covers the public declarations in {len(list(root.glob('*.h')))} C++ headers.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.github/scripts/check-cpp-docs.test.py b/.github/scripts/check-cpp-docs.test.py new file mode 100644 index 00000000..fd50aaa2 --- /dev/null +++ b/.github/scripts/check-cpp-docs.test.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +"""Regression checks for C++ documentation coverage.""" + +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path +from tempfile import TemporaryDirectory +import unittest + + +script = Path(__file__).with_name("check-cpp-docs.py") +spec = spec_from_file_location("check_cpp_docs", script) +module = module_from_spec(spec) +spec.loader.exec_module(module) + + +class DocumentationCoverageTests(unittest.TestCase): + def validate(self, source: str) -> list[str]: + with TemporaryDirectory() as directory: + path = Path(directory) / "Test.h" + path.write_text(source) + return module.validate_header(path) + + def test_undocumented_concept_is_rejected(self): + self.assertTrue(self.validate("template \nconcept CExample = true;\n")) + + def test_bilingual_concept_with_type_parameter_is_accepted(self): + source = """/// +/// Checks an example. +/// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€. +/// +/// The type. +template +concept CExample = true; +""" + self.assertEqual(self.validate(source), []) + + def test_undocumented_public_member_is_rejected(self): + source = """/// +/// A holder. +/// Π₯Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅. +/// +struct Holder { + using Value = int; +}; +""" + self.assertTrue(any("alias" in error for error in self.validate(source))) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/workflows/cpp-docs.yml b/.github/workflows/cpp-docs.yml new file mode 100644 index 00000000..904d8356 --- /dev/null +++ b/.github/workflows/cpp-docs.yml @@ -0,0 +1,50 @@ +name: C++ documentation + +on: + push: + branches: [main] + paths: + - 'cpp/Platform.Interfaces/**' + - 'cpp/Doxyfile' + - '.github/scripts/check-cpp-docs.py' + - '.github/scripts/check-cpp-docs.test.py' + - '.github/workflows/cpp-docs.yml' + pull_request: + branches: [main] + paths: + - 'cpp/Platform.Interfaces/**' + - 'cpp/Doxyfile' + - '.github/scripts/check-cpp-docs.py' + - '.github/scripts/check-cpp-docs.test.py' + - '.github/workflows/cpp-docs.yml' + +jobs: + build: + runs-on: ubuntu-24.04 + timeout-minutes: 10 + permissions: + contents: read + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + - name: Install Doxygen + run: | + sudo apt-get update + sudo apt-get install -y doxygen + - name: Check documentation coverage + run: | + python3 .github/scripts/check-cpp-docs.test.py + python3 .github/scripts/check-cpp-docs.py + - name: Generate documentation + run: | + doxygen cpp/Doxyfile + test -s cpp/docs/html/index.html + test -s cpp/docs/xml/index.xml + - name: Upload HTML and XML documentation + uses: actions/upload-artifact@v4 + with: + name: cpp-api-documentation + path: | + cpp/docs/html + cpp/docs/xml diff --git a/.gitignore b/.gitignore index c489eb5b..8b3ea174 100644 --- a/.gitignore +++ b/.gitignore @@ -326,6 +326,9 @@ ASALocalRun/ # Generated DocFX site csharp/_site/ +# Generated Doxygen site +cpp/docs/ + # NVidia Nsight GPU debugger configuration file *.nvuser diff --git a/README.md b/README.md index 066ef74b..7b5d8595 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ NuGet package: [Platform.Interfaces](https://www.nuget.org/packages/Platform.Int [PDF file](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.pdf) with code for e-readers. +The [C++ documentation workflow](https://github.com/linksplatform/Interfaces/actions/workflows/cpp-docs.yml) generates an HTML and XML API reference as a downloadable artifact. Run `doxygen cpp/Doxyfile` from the repository root to build it locally. + [API documentation PDF](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.Documentation.pdf) generated by DocFX. ## Dependent libraries diff --git a/cpp/Doxyfile b/cpp/Doxyfile new file mode 100644 index 00000000..da8a1e3b --- /dev/null +++ b/cpp/Doxyfile @@ -0,0 +1,27 @@ +PROJECT_NAME = "Platform.Interfaces C++" +# Run from the repository root. The output is ignored locally and uploaded by CI. +OUTPUT_DIRECTORY = cpp/docs +INPUT = cpp/Platform.Interfaces +FILE_PATTERNS = *.h +RECURSIVE = NO +GENERATE_HTML = YES +GENERATE_LATEX = NO +GENERATE_XML = YES +HAVE_DOT = NO +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_AS_ERROR = FAIL_ON_WARNINGS +QUIET = YES +EXCLUDE_SYMBOLS = Platform::Interfaces::Internal +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +# These replacements let Doxygen parse template bases and macro-generated methods. +# The original declarations remain unchanged in the published headers. +PREDEFINED = "THIS_REFERENCE_WRAPPER_METHODS(x,y)=" \ + "VARIABLE_WRAPPER_METHODS(x,y)=" \ + "USE_ALL_BASE_CONSTRUCTORS(x,y)=" \ + "EXTENDED_BASE_TYPE(a,b,c,d,e)=c" \ + "DECORATED_BASE_TYPE(a,b,c,d,e)=c" diff --git a/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec b/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec index c7be134c..66245894 100644 --- a/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec +++ b/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec @@ -5,8 +5,8 @@ LinksPlatform's Platform.Interfaces Template Library LinksPlatform's Platform.Interfaces is a Template Library what contains common concepts templates. LinksPlatform's Platform.Interfaces is a Template Library what contains set of C++ concepts templates. Use Platform.Interfaces.h file to include the library. - Breaking change: rename ICriterionMatcher to IMatcher and CCriterionMatcher to CMatcher. Update header includes and references. - 0.4.0 + Add bilingual documentation for the complete public C++ API and validate generated API documentation in CI. + 0.4.1 konard, uselessgoddess, Mitron57 konard, uselessgoddess, Mitron57 konard, uselessgoddess, Mitron57 From 9464b471322ee19d93be43c75071d1ac27309cef Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 26 Sep 2026 02:35:43 +0000 Subject: [PATCH 6/8] Simplify C++ documentation coverage validation --- .github/scripts/check-cpp-docs.py | 77 +++++++++++++++++++------------ 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/.github/scripts/check-cpp-docs.py b/.github/scripts/check-cpp-docs.py index 9e9a08c7..75ab1e49 100644 --- a/.github/scripts/check-cpp-docs.py +++ b/.github/scripts/check-cpp-docs.py @@ -38,6 +38,51 @@ def documentation_before(lines: list[str], index: int) -> tuple[str, str]: return "\n".join(reversed(comment)), template +def summary_errors(comment: str, label: str) -> list[str]: + errors = [] + if "" not in comment or "" not in comment: + return [f"{label} lacks a documentation summary"] + paragraphs = re.findall(r"(.*?)", comment) + if not any(re.search(r"[A-Za-z]", paragraph) for paragraph in paragraphs) or not any( + re.search(r"[А-Π―Π°-яЁё]", paragraph) for paragraph in paragraphs + ): + errors.append(f"{label} lacks English and Russian paragraphs") + return errors + + +def template_errors(comment: str, template: str, label: str) -> list[str]: + parameters = dict.fromkeys(re.findall(r"\bT(?:[A-Z]\w*)?\b", template)) + return [ + f"{label} lacks documentation for {parameter}" + for parameter in parameters + if f'' not in comment + ] + + +def callable_errors(comment: str, signature: str, kind: str, label: str) -> list[str]: + errors = [] + arguments = re.search(r"\((.*?)\)", signature) + if arguments: + for argument in arguments.group(1).split(","): + name = re.search(r"(\w+)$", argument.strip()) + if name and f'' not in comment: + errors.append(f"{label} lacks documentation for argument {name.group(1)}") + if kind == "method" and not ("virtual void " in signature or "virtual ~" in signature) and "" not in comment: + errors.append(f"{label} lacks return documentation") + return errors + + +def declaration_errors(lines: list[str], index: int, kind: str, path: Path) -> list[str]: + comment, template = documentation_before(lines, index) + label = f"{path}:{index + 1}: {kind}" + errors = summary_errors(comment, label) + if kind == "type": + errors.extend(template_errors(comment, template, label)) + if kind in {"method", "constructor"}: + errors.extend(callable_errors(comment, lines[index].strip(), kind, label)) + return errors + + def validate_header(path: Path) -> list[str]: lines = path.read_text(encoding="utf-8-sig").splitlines() errors = [] @@ -51,36 +96,8 @@ def validate_header(path: Path) -> list[str]: if inside_internal: continue kind = declaration_kind(line) - if kind is None: - continue - comment, template = documentation_before(lines, index) - label = f"{path}:{index + 1}: {kind}" - if "" not in comment or "" not in comment: - errors.append(f"{label} lacks a documentation summary") - continue - paragraphs = re.findall(r"(.*?)", comment) - if not any(re.search(r"[A-Za-z]", paragraph) for paragraph in paragraphs) or not any( - re.search(r"[А-Π―Π°-яЁё]", paragraph) for paragraph in paragraphs - ): - errors.append(f"{label} lacks English and Russian paragraphs") - if kind == "type": - parameters = dict.fromkeys(re.findall(r"\bT(?:[A-Z]\w*)?\b", template)) - for parameter in parameters: - if f'' not in comment: - errors.append(f"{label} lacks documentation for {parameter}") - if kind in {"method", "constructor"}: - signature = line.strip() - arguments = re.search(r"\((.*?)\)", signature) - if arguments: - for argument in arguments.group(1).split(","): - argument = argument.strip() - if not argument: - continue - name = re.search(r"(\w+)$", argument) - if name and f'' not in comment: - errors.append(f"{label} lacks documentation for argument {name.group(1)}") - if kind == "method" and not ("virtual void " in signature or "virtual ~" in signature) and "" not in comment: - errors.append(f"{label} lacks return documentation") + if kind is not None: + errors.extend(declaration_errors(lines, index, kind, path)) return errors From 3b20eda9bff608b0cf7f1d88f60dc4e9d3ca6b7f Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 26 Sep 2026 02:37:55 +0000 Subject: [PATCH 7/8] Document primary interface templates and enforce their coverage --- .github/scripts/check-cpp-docs.py | 4 +++- .github/scripts/check-cpp-docs.test.py | 3 +++ cpp/Platform.Interfaces/ICounter[TResult, TArgument].h | 4 ++++ cpp/Platform.Interfaces/ICounter[TResult].h | 4 ++++ cpp/Platform.Interfaces/IFactory.h | 4 ++++ cpp/Platform.Interfaces/IMatcher.h | 4 ++++ cpp/Platform.Interfaces/IProperties.h | 4 ++++ cpp/Platform.Interfaces/IProperty.h | 4 ++++ cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h | 4 ++++ cpp/Platform.Interfaces/IProvider[TProvided].h | 4 ++++ cpp/Platform.Interfaces/ISetter[TValue, TArgument].h | 4 ++++ cpp/Platform.Interfaces/ISetter[TValue].h | 4 ++++ 12 files changed, 46 insertions(+), 1 deletion(-) diff --git a/.github/scripts/check-cpp-docs.py b/.github/scripts/check-cpp-docs.py index 75ab1e49..d7bca592 100644 --- a/.github/scripts/check-cpp-docs.py +++ b/.github/scripts/check-cpp-docs.py @@ -8,7 +8,9 @@ def declaration_kind(line: str) -> str | None: stripped = line.strip() - if re.match(r"(?:concept|struct|class)\s+\w+", stripped) and ("{" in stripped or "=" in stripped): + if re.match(r"(?:struct|class)\s+\w+", stripped): + return "type" + if re.match(r"concept\s+\w+\s*=", stripped): return "type" if re.match(r"using\s+\w+\s*=", stripped): return "alias" diff --git a/.github/scripts/check-cpp-docs.test.py b/.github/scripts/check-cpp-docs.test.py index fd50aaa2..ec6a6a56 100644 --- a/.github/scripts/check-cpp-docs.test.py +++ b/.github/scripts/check-cpp-docs.test.py @@ -23,6 +23,9 @@ def validate(self, source: str) -> list[str]: def test_undocumented_concept_is_rejected(self): self.assertTrue(self.validate("template \nconcept CExample = true;\n")) + def test_undocumented_primary_template_is_rejected(self): + self.assertTrue(self.validate("template \nstruct IExample;\n")) + def test_bilingual_concept_with_type_parameter_is_accepted(self): source = """/// /// Checks an example. diff --git a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h index 4c04d097..06636c05 100644 --- a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h +++ b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary counter interface template for its supported specializations. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса счётчика для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… спСциализаций. + /// template struct ICounter; diff --git a/cpp/Platform.Interfaces/ICounter[TResult].h b/cpp/Platform.Interfaces/ICounter[TResult].h index f0bd70e4..0de0de5c 100644 --- a/cpp/Platform.Interfaces/ICounter[TResult].h +++ b/cpp/Platform.Interfaces/ICounter[TResult].h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary counter interface template for its supported specializations. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса счётчика для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… спСциализаций. + /// template struct ICounter; diff --git a/cpp/Platform.Interfaces/IFactory.h b/cpp/Platform.Interfaces/IFactory.h index 46a78118..c859db90 100644 --- a/cpp/Platform.Interfaces/IFactory.h +++ b/cpp/Platform.Interfaces/IFactory.h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary factory interface template. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ. + /// template struct IFactory; diff --git a/cpp/Platform.Interfaces/IMatcher.h b/cpp/Platform.Interfaces/IMatcher.h index 9bc93c94..a339590e 100644 --- a/cpp/Platform.Interfaces/IMatcher.h +++ b/cpp/Platform.Interfaces/IMatcher.h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary matcher interface template. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса сопоставлСния. + /// template struct IMatcher; diff --git a/cpp/Platform.Interfaces/IProperties.h b/cpp/Platform.Interfaces/IProperties.h index b0d31482..7885d064 100644 --- a/cpp/Platform.Interfaces/IProperties.h +++ b/cpp/Platform.Interfaces/IProperties.h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary properties operator interface template. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° свойств. + /// template struct IProperties; diff --git a/cpp/Platform.Interfaces/IProperty.h b/cpp/Platform.Interfaces/IProperty.h index fdd012f2..97b70a04 100644 --- a/cpp/Platform.Interfaces/IProperty.h +++ b/cpp/Platform.Interfaces/IProperty.h @@ -4,6 +4,10 @@ #include "ISetter[TValue, TArgument].h" namespace Platform::Interfaces { + /// + /// Declares the primary property operator interface template. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° свойства. + /// template struct IProperty; diff --git a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h index 356f0a36..eb81d7d2 100644 --- a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h +++ b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary provider interface template for its supported specializations. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса поставщика для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… спСциализаций. + /// template struct IProvider; diff --git a/cpp/Platform.Interfaces/IProvider[TProvided].h b/cpp/Platform.Interfaces/IProvider[TProvided].h index 7e9b7069..0609464a 100644 --- a/cpp/Platform.Interfaces/IProvider[TProvided].h +++ b/cpp/Platform.Interfaces/IProvider[TProvided].h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary provider interface template for its supported specializations. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса поставщика для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… спСциализаций. + /// template struct IProvider; diff --git a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h index 5c7d1f24..805cfafe 100644 --- a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h +++ b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary setter interface template for its supported specializations. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса установщика для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… спСциализаций. + /// template struct ISetter; diff --git a/cpp/Platform.Interfaces/ISetter[TValue].h b/cpp/Platform.Interfaces/ISetter[TValue].h index 63d1e663..f49d75b0 100644 --- a/cpp/Platform.Interfaces/ISetter[TValue].h +++ b/cpp/Platform.Interfaces/ISetter[TValue].h @@ -1,6 +1,10 @@ ο»Ώ#pragma once namespace Platform::Interfaces { + /// + /// Declares the primary setter interface template for its supported specializations. + /// ΠžΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ основной шаблон интСрфСйса установщика для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… спСциализаций. + /// template struct ISetter; From 210bd621bf66e78e853cd7a6b719be398615cb5b Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 26 Sep 2026 02:47:19 +0000 Subject: [PATCH 8/8] Validate bilingual C# API documentation in CI --- .github/scripts/check-csharp-docs.py | 59 +++++++++++++++++++ .github/scripts/check-csharp-docs.test.py | 48 +++++++++++++++ .github/scripts/validate-csharp-package.sh | 2 +- .github/workflows/csharp.yml | 5 ++ README.md | 4 +- .../Platform.Interfaces.csproj | 4 +- 6 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 .github/scripts/check-csharp-docs.py create mode 100644 .github/scripts/check-csharp-docs.test.py diff --git a/.github/scripts/check-csharp-docs.py b/.github/scripts/check-csharp-docs.py new file mode 100644 index 00000000..d3d1dea4 --- /dev/null +++ b/.github/scripts/check-csharp-docs.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +"""Require English and Russian paragraphs in generated C# API documentation.""" + +from pathlib import Path +import re +import sys +import xml.etree.ElementTree as ET + + +DOCUMENTATION_TAGS = {"summary", "remarks", "typeparam", "param", "returns", "value", "example", "exception"} + + +def has_bilingual_paragraphs(element: ET.Element) -> bool: + paragraphs = ["".join(paragraph.itertext()) for paragraph in element.findall("para")] + return any(re.search(r"[A-Za-z]", paragraph) for paragraph in paragraphs) and any( + re.search(r"[А-Π―Π°-яЁё]", paragraph) for paragraph in paragraphs + ) + + +def validate_xml(path: Path) -> list[str]: + root = ET.parse(path).getroot() + members = root.findall("./members/member") + if not members: + return [f"{path}: generated XML contains no documented API members"] + + errors = [] + for member in members: + name = member.get("name", "unnamed member") + if member.find("summary") is None: + errors.append(f"{name}: missing summary") + for section in member: + if section.tag not in DOCUMENTATION_TAGS: + continue + label = f"{section.tag} {section.get('name', '')}".strip() + if not has_bilingual_paragraphs(section): + errors.append(f"{name}: {label} lacks English and Russian paragraphs") + return errors + + +def main() -> int: + if len(sys.argv) != 2: + print("Usage: check-csharp-docs.py XML_FILE", file=sys.stderr) + return 2 + path = Path(sys.argv[1]) + try: + errors = validate_xml(path) + except (OSError, ET.ParseError) as error: + print(f"{path}: {error}", file=sys.stderr) + return 1 + if errors: + print("\n".join(errors), file=sys.stderr) + return 1 + count = len(ET.parse(path).getroot().findall("./members/member")) + print(f"Validated bilingual XML documentation for {count} C# API members.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.github/scripts/check-csharp-docs.test.py b/.github/scripts/check-csharp-docs.test.py new file mode 100644 index 00000000..1fe527e5 --- /dev/null +++ b/.github/scripts/check-csharp-docs.test.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +"""Regression checks for generated C# XML documentation.""" + +from importlib.util import module_from_spec, spec_from_file_location +from pathlib import Path +from tempfile import TemporaryDirectory +import unittest + + +script = Path(__file__).with_name("check-csharp-docs.py") +spec = spec_from_file_location("check_csharp_docs", script) +module = module_from_spec(spec) +spec.loader.exec_module(module) + + +class DocumentationCoverageTests(unittest.TestCase): + def validate(self, content: str) -> list[str]: + with TemporaryDirectory() as directory: + path = Path(directory) / "Platform.Interfaces.xml" + path.write_text(content, encoding="utf-8") + return module.validate_xml(path) + + def test_bilingual_member_and_parameter_are_accepted(self): + xml = """ + Runs.ЗапускаСт. + Input.Π’Π²ΠΎΠ΄. + """ + self.assertEqual(self.validate(xml), []) + + def test_missing_russian_summary_is_rejected(self): + xml = """ + An example. + """ + self.assertTrue(any("summary" in error for error in self.validate(xml))) + + def test_missing_english_parameter_is_rejected(self): + xml = """ + Runs.ЗапускаСт. + Π’Π²ΠΎΠ΄. + """ + self.assertTrue(any("param input" in error for error in self.validate(xml))) + + def test_empty_member_list_is_rejected(self): + self.assertTrue(self.validate("")) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/scripts/validate-csharp-package.sh b/.github/scripts/validate-csharp-package.sh index 4255424d..9f082834 100755 --- a/.github/scripts/validate-csharp-package.sh +++ b/.github/scripts/validate-csharp-package.sh @@ -33,7 +33,7 @@ if [[ ${#symbol_packages[@]} -ne 0 ]]; then fi package_contents=$(unzip -Z1 "${packages[0]}") -for expected_file in README.md icon.png lib/net8.0/Platform.Interfaces.dll; do +for expected_file in README.md icon.png lib/net8.0/Platform.Interfaces.dll lib/net8.0/Platform.Interfaces.xml; do if ! grep -Fxq "$expected_file" <<< "$package_contents"; then echo "${packages[0]} is missing $expected_file." >&2 exit 1 diff --git a/.github/workflows/csharp.yml b/.github/workflows/csharp.yml index 4ade993d..b4597ccb 100644 --- a/.github/workflows/csharp.yml +++ b/.github/workflows/csharp.yml @@ -47,6 +47,11 @@ jobs: - name: Validate tests and NuGet package run: ../.github/scripts/validate-csharp-package.sh + - name: Validate bilingual C# API documentation + run: | + python3 ../.github/scripts/check-csharp-docs.test.py + python3 ../.github/scripts/check-csharp-docs.py Platform.Interfaces/bin/Release/net8/Platform.Interfaces.xml + - name: Test C# workflow safeguards run: node --test ../.github/scripts/*csharp*.test.mjs diff --git a/README.md b/README.md index 7b5d8595..34accc99 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,9 @@ NuGet package: [Platform.Interfaces](https://www.nuget.org/packages/Platform.Int [PDF file](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.pdf) with code for e-readers. -The [C++ documentation workflow](https://github.com/linksplatform/Interfaces/actions/workflows/cpp-docs.yml) generates an HTML and XML API reference as a downloadable artifact. Run `doxygen cpp/Doxyfile` from the repository root to build it locally. +The [C++ documentation workflow](https://github.com/linksplatform/Interfaces/actions/workflows/cpp-docs.yml) checks bilingual English/Russian comments and generates an HTML and XML API reference as a downloadable artifact. Run `doxygen cpp/Doxyfile` from the repository root to build it locally. -[API documentation PDF](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.Documentation.pdf) generated by DocFX. +The [C# workflow](https://github.com/linksplatform/Interfaces/actions/workflows/csharp.yml) checks bilingual XML comments and publishes the DocFX site, including the [API documentation PDF](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.Documentation.pdf). ## Dependent libraries * [Platform.Collections](https://github.com/linksplatform/Collections) diff --git a/csharp/Platform.Interfaces/Platform.Interfaces.csproj b/csharp/Platform.Interfaces/Platform.Interfaces.csproj index f05f43fc..ca685aba 100644 --- a/csharp/Platform.Interfaces/Platform.Interfaces.csproj +++ b/csharp/Platform.Interfaces/Platform.Interfaces.csproj @@ -4,7 +4,7 @@ LinksPlatform's Platform.Interfaces Class Library Konstantin Diachenko Platform.Interfaces - 0.6.0 + 0.6.1 Konstantin Diachenko net8 Platform.Interfaces @@ -23,7 +23,7 @@ true embedded latest - Breaking change: rename ICriterionMatcher to IMatcher. Matcher input is named candidate; update implementations and references to the new interface. + Validate complete bilingual English and Russian XML documentation for the public C# API in CI. enable