diff --git a/.github/scripts/check-cpp-docs.py b/.github/scripts/check-cpp-docs.py
new file mode 100644
index 0000000..d7bca59
--- /dev/null
+++ b/.github/scripts/check-cpp-docs.py
@@ -0,0 +1,117 @@
+#!/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"(?: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"
+ 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 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 = []
+ 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 not None:
+ errors.extend(declaration_errors(lines, index, kind, path))
+ 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 0000000..ec6a6a5
--- /dev/null
+++ b/.github/scripts/check-cpp-docs.test.py
@@ -0,0 +1,53 @@
+#!/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_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.
+/// Проверяет пример.
+///
+/// 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/scripts/check-csharp-docs.py b/.github/scripts/check-csharp-docs.py
new file mode 100644
index 0000000..d3d1dea
--- /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 0000000..1fe527e
--- /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 4255424..9f08283 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/cpp-docs.yml b/.github/workflows/cpp-docs.yml
new file mode 100644
index 0000000..904d835
--- /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/.github/workflows/csharp.yml b/.github/workflows/csharp.yml
index 4ade993..b4597cc 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/.gitignore b/.gitignore
index c489eb5..8b3ea17 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 066ef74..34accc9 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +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.
-[API documentation PDF](https://linksplatform.github.io/Interfaces/csharp/Platform.Interfaces.Documentation.pdf) generated by DocFX.
+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.
+
+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/cpp/Doxyfile b/cpp/Doxyfile
new file mode 100644
index 0000000..da8a1e3
--- /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/CArray.h b/cpp/Platform.Interfaces/CArray.h
index fa68e64..a99ff80 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 2843a8c..f5c599a 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 587ab24..d6d124a 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 25f8cff..a72be95 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 66659ed..2095d96 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 fee54c7..726caf7 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 5f0671c..9951e3c 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 e9624f1..1b8cdf2 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 3d76aeb..f55173f 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 b1dfb6c..6e38f6c 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 66f8b22..aff3787 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 15fb825..fd94c3b 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 532058e..a13c17a 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 a68711f..678dfcf 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 b61e436..d1f2bce 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 72125d1..2b3c2f4 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 773448f..a053042 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 e274a85..a55537b 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 98488e7..bc9e748 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 da763ee..14b3467 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 1a5c0b5..d0db2e1 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 707f8ad..14438d6 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 87f1eb0..3395637 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 9313f67..c2cdbb3 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 ecd077f..b4864d3 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 86edc18..b7356b9 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 0009155..06636c0 100644
--- a/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h
+++ b/cpp/Platform.Interfaces/ICounter[TResult, TArgument].h
@@ -1,13 +1,45 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary counter interface template for its supported specializations.
+ /// Объявляет основной шаблон интерфейса счётчика для поддерживаемых специализаций.
+ ///
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;
+ ///
+ /// 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 44db546..0de0de5 100644
--- a/cpp/Platform.Interfaces/ICounter[TResult].h
+++ b/cpp/Platform.Interfaces/ICounter[TResult].h
@@ -1,13 +1,37 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary counter interface template for its supported specializations.
+ /// Объявляет основной шаблон интерфейса счётчика для поддерживаемых специализаций.
+ ///
template
struct ICounter;
+ ///
+ /// Defines a counter.
+ /// Определяет счётчик.
+ ///
+ ///
+ /// The count result type.
+ /// Тип результата подсчёта.
+ ///
template
struct ICounter {
+ ///
+ /// Performs a count.
+ /// Выполняет подсчёт.
+ ///
+ ///
+ /// The count result.
+ /// Результат подсчёта.
+ ///
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 5d7c6b3..c859db9 100644
--- a/cpp/Platform.Interfaces/IFactory.h
+++ b/cpp/Platform.Interfaces/IFactory.h
@@ -1,13 +1,37 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary factory interface template.
+ /// Объявляет основной шаблон интерфейса фабрики.
+ ///
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;
+ ///
+ /// 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 017f96b..a339590 100644
--- a/cpp/Platform.Interfaces/IMatcher.h
+++ b/cpp/Platform.Interfaces/IMatcher.h
@@ -1,13 +1,41 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary matcher interface template.
+ /// Объявляет основной шаблон интерфейса сопоставления.
+ ///
template
struct IMatcher;
+ ///
+ /// Defines a matcher that determines whether a candidate satisfies its matching rule.
+ /// Определяет объект, который проверяет, соответствует ли кандидат правилу сопоставления.
+ ///
+ ///
+ /// Type of the value being tested for a match.
+ /// Тип значения, проверяемого на соответствие.
+ ///
template
struct IMatcher {
+ ///
+ /// Determines whether the candidate satisfies the matching rule.
+ /// Определяет, соответствует ли кандидат правилу сопоставления.
+ ///
+ ///
+ /// The value to test.
+ /// Проверяемое значение.
+ ///
+ ///
+ /// Whether the candidate satisfies the matching rule.
+ /// Соответствует ли кандидат правилу сопоставления.
+ ///
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 ff0871c..7885d06 100644
--- a/cpp/Platform.Interfaces/IProperties.h
+++ b/cpp/Platform.Interfaces/IProperties.h
@@ -1,15 +1,71 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary properties operator interface template.
+ /// Объявляет основной шаблон интерфейса оператора свойств.
+ ///
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;
+ ///
+ /// 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 f36e9e9..97b70a0 100644
--- a/cpp/Platform.Interfaces/IProperty.h
+++ b/cpp/Platform.Interfaces/IProperty.h
@@ -4,11 +4,31 @@
#include "ISetter[TValue, TArgument].h"
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary property operator interface template.
+ /// Объявляет основной шаблон интерфейса оператора свойства.
+ ///
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 {
+ ///
+ /// 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 119cadc..eb81d7d 100644
--- a/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h
+++ b/cpp/Platform.Interfaces/IProvider[TProvided, TArgument].h
@@ -1,13 +1,45 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary provider interface template for its supported specializations.
+ /// Объявляет основной шаблон интерфейса поставщика для поддерживаемых специализаций.
+ ///
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;
+ ///
+ /// 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 2f035f3..0609464 100644
--- a/cpp/Platform.Interfaces/IProvider[TProvided].h
+++ b/cpp/Platform.Interfaces/IProvider[TProvided].h
@@ -1,13 +1,37 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary provider interface template for its supported specializations.
+ /// Объявляет основной шаблон интерфейса поставщика для поддерживаемых специализаций.
+ ///
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;
+ ///
+ /// 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 52ed8b9..805cfaf 100644
--- a/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h
+++ b/cpp/Platform.Interfaces/ISetter[TValue, TArgument].h
@@ -1,13 +1,45 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary setter interface template for its supported specializations.
+ /// Объявляет основной шаблон интерфейса установщика для поддерживаемых специализаций.
+ ///
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;
+ ///
+ /// 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 a893933..f49d75b 100644
--- a/cpp/Platform.Interfaces/ISetter[TValue].h
+++ b/cpp/Platform.Interfaces/ISetter[TValue].h
@@ -1,13 +1,37 @@
#pragma once
namespace Platform::Interfaces {
+ ///
+ /// Declares the primary setter interface template for its supported specializations.
+ /// Объявляет основной шаблон интерфейса установщика для поддерживаемых специализаций.
+ ///
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;
+ ///
+ /// 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 061b5e0..5f3bc6c 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/Platform.Interfaces.TemplateLibrary.nuspec b/cpp/Platform.Interfaces/Platform.Interfaces.TemplateLibrary.nuspec
index c7be134..6624589 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
diff --git a/cpp/Platform.Interfaces/Polymorph.h b/cpp/Platform.Interfaces/Polymorph.h
index e182ffe..00340c3 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
diff --git a/csharp/Platform.Interfaces/Platform.Interfaces.csproj b/csharp/Platform.Interfaces/Platform.Interfaces.csproj
index f05f43f..ca685ab 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